В Oracle можно ли «вставить» столбец в таблицу?

При добавлении столбца в существующую таблицу Oracle всегда помещает столбец в конец таблицы. Можно ли указать Oracle, где он должен отображаться в таблице? Если да, то как?

Ответов (9)

Обычно я делаю следующее:

  1. Переименуйте старую таблицу.
  2. Создайте новую таблицу со столбцами в правильном порядке.
  3. Создайте ограничения для этой новой таблицы.
  4. Заполнить данными: вставить в new_table выберите * из переименованной таблицы.

Расположение столбца в таблице не должно иметь значения (если только нет «размеров страницы», которые следует учитывать, или того, что Oracle использует для фактического хранения данных). Для потребителя важнее то, как вызываются результаты, то есть оператор Select.

Я в это не верю - SQL Server этого тоже не допускает. Я всегда должен использовать следующий метод:

  1. Создайте новую таблицу, которая выглядит правильно (включая дополнительный столбец
  2. Начать транзакцию
  3. выбрать все данные из старой таблицы в новую
  4. Удалить старую таблицу
  5. Переименовать новую таблицу
  6. Зафиксировать транзакцию.

Не совсем красиво, но выполняет свою работу.

Я не думаю, что это можно сделать без сохранения данных во временную таблицу, удаления таблицы и ее воссоздания. С другой стороны, на самом деле не имеет значения, где находится столбец. Пока вы указываете столбцы, которые вы извлекаете в своем операторе select, вы можете упорядочить их, как хотите.

переименуйте YOUR_ORIGINAL_TABLE в YOUR_NEW_TABLE;

создать таблицу YOUR_ORIGINAL_TABLE с отсутствием / * или невосстановимостью * / как выберите Column1, Column2, NEW_COLUMN, Column3 из YOUR_NEW_TABLE;

Удалить таблицу YOUR_NEW_TABLE;

Выберите * Из YOUR_ORIGINAL_TABLE; <<<<< теперь вы увидите новый столбец посередине таблицы.

Но зачем вам это делать? Это кажется нелогичным. Никогда не следует предполагать порядок столбцов и просто использовать список именованных столбцов, если порядок столбцов важен.

Нет, это невозможно с помощью оператора «ALTER TABLE». Однако вы можете создать новую таблицу с тем же определением, что и ваша текущая, хотя и с другим именем, со столбцами в правильном порядке, как вы хотите. Скопируйте данные в новую таблицу. Бросьте старый стол. Переименуйте новую таблицу в соответствии со старым именем таблицы.

У Тома Кайта есть статья об этом в тексте ссылки на AskTom.

Почему порядок столбцов имеет значение? Вы всегда можете изменить его в своем операторе выбора?

Добавление новых столбцов в конец таблицы дает преимущество. Если есть код, который наивно выполняет «SELECT *», а затем анализирует поля по порядку, вы не нарушите старый код, добавив в конце новые столбцы. Если вы добавите новые столбцы в середину таблицы, старый код может быть поврежден.

На одной работе у меня был администратор базы данных, который был супер-аналом насчет «Никогда не делай 'SELECT *'». Он настаивал, чтобы вы всегда записывали конкретные поля.

Имейте в виду, что под таблицами все данные в записях таблицы склеены. Добавление столбца в конец таблицы [если он допускает значение NULL или (в более поздних версиях) не NULL по умолчанию] просто означает изменение метаданных таблицы. Добавление столбца посередине потребует переписывания каждой записи в этой таблице, чтобы добавить соответствующее значение (или маркеры) для этого столбца. В некоторых случаях это может означать, что записи занимают больше места в блоках, и некоторые записи необходимо перенести. Короче говоря, для таблицы любого реального размера это огромное количество операций ввода-вывода.

Вы всегда можете создать представление для таблицы, в которой столбцы расположены в предпочтительном порядке, и использовать это представление в операторе DML так же, как и в таблице.

1) Хорошо, вы не можете сделать это напрямую. Нам не нужен пост за постом, в котором говорится одно и то же, не так ли?

2) Хорошо, поэтому порядок столбцов в таблице технически не имеет значения. Но дело не в этом, исходный вопрос просто спрашивал, можно или нельзя сделать. Не думайте, что вы знаете требования других. Может быть, у них есть таблица со 100 столбцами, которая в настоящее время запрашивается с использованием «SELECT * ...» внутри какого-то чудовищно взломанного запроса, который они просто предпочли бы не пытаться распутывать, не говоря уже о замене «*» на 100 имен столбцов. Или, может быть, они просто озабочены порядком вещей и любят располагать связанные поля рядом друг с другом при просмотре схемы, скажем, с помощью SQL Developer. Возможно, они имеют дело с нетехническим персоналом, который не знает, что нужно смотреть в конец списка из 100 столбцов, когда, по логике, он должен быть где-то в самом начале.

Нет ничего более раздражающего, чем задать честный вопрос и получить ответ, который гласит: «Вы не должны этого делать». Это МОЯ работа, а не ВАША! Пожалуйста, не говорите мне, как делать мою работу. Просто помогите, если сможете. Спасибо!

Хорошо ... извините за тираду. Теперь ... на сайте www.orafaq.com предлагается этот обходной путь.

Сначала предположим, что вы уже запустили:

СОЗДАТЬ ТАБЛИЦУ tab1 (НОМЕР col1);

Теперь предположим, что вы хотите добавить столбец с именем «col2», но вы хотите, чтобы они упорядочены «col2», «col1» при выполнении команды «SELECT * FROM tbl1;»

Предлагается запустить:

ALTER TABLE tab1 ADD (col2 DATE); ПЕРЕИМЕНОВАТЬ tab1 TO tab1_old; СОЗДАТЬ ТАБЛИЦУ tab1 AS SELECT 0 AS col1, col1 AS col2 FROM tab1_old;

Я обнаружил, что это невероятно вводит в заблуждение. Прежде всего, вы заполняете "col1" нулями, поэтому, если у вас есть какие-либо данные, вы теряете их, делая это. Во-вторых, он фактически переименовывает «col1» в «col2» и не упоминает об этом. Итак, вот мой пример, надеюсь, он немного понятнее:

Предположим, у вас есть таблица, созданная с помощью следующего оператора:

СОЗДАТЬ ТАБЛИЦУ пользователей (first_name varchar (25), last_name varchar (25));

Теперь предположим, что вы хотите вставить middle_name между first_name и last_name. Вот один из способов:

Пользователи ALTER TABLE ДОБАВЛЯЮТ middle_name varchar (25); ПЕРЕИМЕНОВАТЬ пользователей НА users_tmp; СОЗДАТЬ ТАБЛИЦУ пользователей КАК ВЫБРАТЬ first_name, middle_name, last_name FROM users_tmp; / * и для удобства ... * / DROP TABLE testusers_tmp;

Обратите внимание, что middle_name по умолчанию будет NULL (подразумевается оператором ALTER TABLE). В качестве альтернативы вы можете установить другое значение по умолчанию в операторе CREATE TABLE следующим образом:

СОЗДАТЬ ТАБЛИЦУ пользователей КАК ВЫБРАТЬ first_name, «какое-то значение по умолчанию» AS middle_name, last_name FROM users_tmp;

Этот трюк может пригодиться, если вы добавляете поле даты со значением по умолчанию sysdate, но хотите, чтобы все существующие записи имели другое (например, более раннее) значение даты.