Как экспортировать сценарий ddl из схемы Oracle 10 для создания таблиц и ограничений в базе данных H2?
Мы хотели бы использовать базу данных H2 в памяти для автоматического тестирования наших веб-приложений. Мы используем Oracle 10 для наших сред производства и разработки.
Таким образом, идея состоит в том, чтобы продублировать структуру таблицы в тестовой базе данных H2, как в нашей базе данных разработчика Oracle.
Есть ли простой способ извлечь DDL из схемы Oracle 10 (таблицы и ограничения), чтобы их можно было выполнять с базой данных H2?
4 ответа
Этот сценарий помог мне:
create or replace function mymetadata return sys.ku$_ddls is
md_handle number;
tr_handle number;
dl_handle number;
result_array sys.ku$_ddls;
begin
md_handle := dbms_metadata.open('TABLE');
tr_handle := dbms_metadata.add_transform(md_handle, 'MODIFY');
dbms_metadata.set_remap_param(tr_handle, 'REMAP_SCHEMA', 'MLIS_DEV', null);
dl_handle := dbms_metadata.add_transform(md_handle, 'DDL');
dbms_metadata.set_transform_param(dl_handle, 'SEGMENT_ATTRIBUTES', false);
dbms_metadata.set_transform_param(dl_handle, 'STORAGE', false);
dbms_metadata.set_transform_param(dl_handle, 'TABLESPACE', false);
dbms_metadata.set_transform_param(dl_handle, 'REF_CONSTRAINTS', false);
dbms_metadata.set_transform_param(dl_handle, 'SQLTERMINATOR', true);
dbms_metadata.set_transform_param(dl_handle, 'CONSTRAINTS_AS_ALTER', true);
LOOP
result_array := dbms_metadata.fetch_ddl(md_handle);
EXIT WHEN result_array IS NULL;
FOR i IN result_array.FIRST..result_array.LAST LOOP
dbms_output.put_line(result_array(i).ddltext);
END LOOP;
END LOOP;
dbms_metadata.close(md_handle);
md_handle := dbms_metadata.open('REF_CONSTRAINT');
tr_handle := dbms_metadata.add_transform(md_handle, 'MODIFY');
dbms_metadata.set_remap_param(tr_handle, 'REMAP_SCHEMA', 'MLIS_DEV', null);
dl_handle := dbms_metadata.add_transform(md_handle, 'DDL');
dbms_metadata.set_transform_param(dl_handle, 'SQLTERMINATOR', true);
LOOP
result_array := dbms_metadata.fetch_ddl(md_handle);
EXIT WHEN result_array IS NULL;
FOR i IN result_array.FIRST..result_array.LAST LOOP
dbms_output.put_line(result_array(i).ddltext);
END LOOP;
END LOOP;
dbms_metadata.close(md_handle);
return result_array;
end;
/
select ddltext from table(mymetadata);
Мне нужно спросить, что вы "доказываете", если в вашей тестовой среде используется другой движок базы данных, чем в реальной реализации. Например, H2 имеет тип данных DATE, который является просто DATE. В Oracle тип данных DATE также хранит время.
Если вы решите пойти по этому пути, то вместо того, чтобы пытаться преобразовать синтаксис Oracle DDL в H2, вам лучше спроектировать структуры данных в инструменте моделирования и использовать его в качестве "источника правды". Инструмент должен быть способен экспортировать / создавать DDL в форматах Oracle и H2. Большинство инструментов должны поддерживать Oracle, хотя H2 может быть немного сложнее.
Вы должны иметь возможность использовать пакет DBMS_METADATA для генерации DDL для всех объектов в вашей схеме. Пару дней назад была дискуссия о том, как программно генерировать DDL из базы данных Oracle, которая, как представляется, находится на подходе.
Я использовал функцию DBeaver для создания DDL.
Удаление конкретных операторов таблицы Oracle, например:
SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 131072 NEXT 131072 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL KEEP FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "data"
и удаление ENABLE в определении столбца, например
"ID" NUMBER(15,0) NOT NULL ENABLE,
и удаление дополнительных атрибутов первичного ключа:
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 131072 NEXT 131072 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT
это позволяло создавать таблицы в h2 версии 1.4.196.
Например, DBeaver 21.1.5 сгенерировал:
Затем удаление ненужных полей дало мне:
CREATE TABLE "CARD_STATE"
("ID" NUMBER(15,0) NOT NULL ,
"NAME" VARCHAR2(32) NOT NULL,
CONSTRAINT "PK_CARD_STATE" PRIMARY KEY ("ID");