Oracle Заполнение резервной таблицы из основной таблицы

StackOverflow https://stackoverflow.com/questions/305797

  •  08-07-2019
  •  | 
  •  

Вопрос

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

Во время проверки кода коллега отметил, что

INSERT INTO BACKUP_TABLE
SELECT *
FROM PRIMARY_TABLE

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

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

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

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

Это было полезно?

Решение

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

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

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.

Другие советы

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

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

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

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

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

INSERT INTO BACKUP_TABLE
SELECT *
FROM PRIMARY_TABLE

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

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

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

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

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

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

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;

Редактировать:

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top