Oracle Заполнить резервную таблицу из первичной таблицы - PullRequest
3 голосов
/ 20 ноября 2008

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

Во время проверки кода сотрудник указал, что

INSERT INTO BACKUP_TABLE
SELECT *
FROM PRIMARY_TABLE

излишне рискованно, поскольку таблицы могут иметь разные столбцы и разные порядки столбцов.

Я также не могу создавать / удалять / переименовывать таблицы. ~ Вздох ~

Ожидается, что столбцы в таблице изменятся, поэтому простое жесткое кодирование названий столбцов на самом деле не является решением, которое я ищу.

Я ищу идеи относительно разумного, не рискованного способа выполнения этой работы.

Ответы [ 5 ]

7 голосов
/ 20 ноября 2008

Сохраняется ли резервная таблица? Сохраняет ли он данные постоянно или это просто копия текущих значений?

Слишком плохо из-за невозможности создать / удалить / переименовать / скопировать. В противном случае, если он краткосрочный, просто используется в случае, если что-то пойдет не так, вы можете отбросить его в начале обработки и сделать что-то вроде

create table backup_table as select * from primary_table;

Лучшим вариантом может быть сделать выбор явным, как

insert into backup_table (<list of columns>) select <list of columns> from primary_table;

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

Возможно, вам захочется сделать это явным и вызвать серьезную ошибку, если backup_table не существует или какой-либо из столбцов в primary_table отсутствует в backup_table.

2 голосов
/ 20 ноября 2008

Как часто вы меняете структуру своих таблиц? Ваш метод должен работать нормально, если структура не меняется. Лично я думаю, что ваши администраторы баз данных должны предоставить вам механизм для удаления резервной таблицы и ее воссоздания, такой как хранимая процедура. У меня было нечто похожее на моей последней работе для усечения определенных таблиц, поскольку усечение часто намного быстрее, чем DELETE FROM TABLE;.

1 голос
/ 16 октября 2009

Если бы у меня была такая ситуация, я бы получил определения столбцов для двух таблиц в самом начале проблемы. Тогда, если бы они были идентичны, я бы начал с простого:

INSERT INTO BACKUP_TABLE
SELECT *
FROM PRIMARY_TABLE

Если бы они отличались, я бы продолжил, только если бы не было критических столбцов, отсутствующих в резервной таблице. В этом случае я бы использовал эту форму для резервной копии:

INSERT INTO BACKUP_TABLE (<list of columns>) 
SELECT <list of columns> 
FROM PRIMARY_TABLE

Но я бы также беспокоился о том, что произойдет, если я просто остановлю программу с ошибкой, поэтому у меня может даже быть план резервного копирования, где я буду использовать вторую форму для столбцов, которые находятся в обеих таблицах, а также для дампа текстовый файл с PK и столбцами, отсутствующими в резервной копии. Также зарегистрируйте ошибку, даже если кажется, что программа завершилась нормально. Таким образом, вы можете восстановить данные, если произойдет худшее.

Действительно, это признак плохих процессов где-то, которые следует устранить, но защитное программирование может помочь сделать это проблемой кого-то другого, а не вашей. Если они не замечают сообщение об ошибке в журнале, которое сообщает им о дампе текста с отсутствующими столбцами, то это не ваша ошибка.

Но, если вы не защитите код и произойдет худшее, это будет частично ваша вина.

1 голос
/ 20 ноября 2008

Есть ли причина, по которой вы не можете просто перечислить столбцы в таблицах? Так

INSERT INTO backup_table( col1, col2, col3, ... colN )
  SELECT col1, col2, col3, ..., colN
    FROM primary_table

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

0 голосов
/ 20 ноября 2008

Вы можете попробовать что-то вроде:

CREATE TABLE secondary_table AS SELECT * FROM primary_table;

Не уверен, что это автоматически копирует данные. Если нет:

CREATE TABLE secondary_table AS SELECT * FROM primary_table LIMIT 1;
INSERT INTO secondary_table SELECT * FROM primary_table;

Edit:

Извините, не прочитал ваше сообщение полностью: особенно часть ограничений. Боюсь, я не знаю как. Я думаю, будет использовать процедуру, которая сначала описывает обе таблицы и сравнивает их перед созданием длинного запроса вставки / выбора.

Тем не менее, если вы используете резервную таблицу, я думаю, что очень важно, чтобы она точно соответствовала исходной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...