Как дублировать все данные в таблице, кроме одного столбца, который должен быть изменен - PullRequest
0 голосов
/ 23 апреля 2010

У меня есть вопрос относительно унифицированного запроса вставки для таблиц с разными данными. структуры (Oracle). Позвольте мне привести пример:

    tb_customers (
    id NUMBER(3), name VARCHAR2(40), archive_id NUMBER(3)
    )

    tb_suppliers (
    id NUMBER(3), name VARCHAR2(40), contact VARCHAR2(40), xxx, xxx, 
    archive_id NUMBER(3)
    )

Единственный столбец, который присутствует во всех таблицах - это [archive_id]. Планируется создать новый архив набора данных, скопировав (продублировав) все записи в другой раздел базы данных и увеличивая соответственно значение archive_id для этих записей. [archive_id] всегда является частью первичного ключа.

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

Одним из решений (которое работает) является перебор всех таблиц в хранимой процедуре и выполнение:

CREATE TABLE temp as (SELECT * from ORIGINAL_TABLE);
UPDATE temp SET archive_id=something;
INSERT INTO ORIGINAL_TABLE (select * from temp);
DROP TABLE temp;

Мне не очень нравится это решение, поскольку команды DDL портят все точки восстановления.

У кого-нибудь еще есть решение?

Ответы [ 2 ]

0 голосов
/ 23 апреля 2010

Я бы предложил не иметь единого оператора sql для всех таблиц, а просто использовать и вставить.

insert into tb_customers_2 
    select id, name, 'new_archive_id' from tb_customers;
insert into tb_suppliers_2 
    select id, name, contact, xxx, xxx, 'new_archive_id' from tb_suppliers;

Или, если вам действительно нужен один SQL-оператор для всех них, по крайней мере, предварительно создайте все временные таблицы (как временные таблицы) и оставьте их на месте в следующий раз. Затем просто используйте динамический sql для ссылки на временную таблицу.

insert into ORIGINAL_TABLE_TEMP (SELECT * from ORIGINAL_TABLE);
UPDATE ORIGINAL_TABLE_TEMP SET archive_id=something;
INSERT INTO NEW_TABLE (select * from ORIGINAL_TABLE_TEMP);
0 голосов
/ 23 апреля 2010

Как насчет создания глобальной временной таблицы для каждой базовой таблицы?

create global temporary table tb_customers$ as select * from tb_customers;
create global temporary table tb_suppliers$ as select * from tb_suppliers;

Вам не нужно каждый раз создавать и удалять их, просто оставьте их как есть.

Ваш архивный процесс - это одна транзакция ...

insert into tb_customers$ as select * from tb_customers;
update tb_customers$ set archive_id = :v_new_archive_id;
insert into tb_customers select * from tb_customers$;

insert into tb_suppliers$ as select * from tb_suppliers;
update tb_suppliers$ set archive_id = :v_new_archive_id;
insert into tb_suppliers select * from tb_suppliers$;

commit; -- this will clear the global temporary tables

Надеюсь, это поможет.

...