Могу ли я использовать DBMS_METADATA для удаления SUPPLEMENTAL LOG GROUP из DDL?
Я хотел бы получить DDL таблицы и создать еще один из нее. В настоящее время у меня есть что-то вроде этого:
v_stmt := 'select dbms_metadata.get_ddl(''TABLE'', ''' || original_table || ''') from dual';
execute immediate v_stmt into v_stmt ;
v_stmt := REGEXP_REPLACE(v_stmt, '(' || original_table || ')', new_table, 1, 1);
execute immediate v_stmt;
В текущей таблице генерируется SUPPLEMENTAL LOG GROUP. Я не хочу этого, или, скорее, когда я пытаюсь создать, я сталкиваюсь с ошибкой ниже.
ORA-30567: name already used by an existing log group
Как избавиться от ГРУППЫ ДОПОЛНИТЕЛЬНЫХ ЛОГОВ? Можно ли использовать что-то вроде ниже или есть какое-то другое решение?
dbms_metadata.set_transform_param(dbms_metadata.session_transform,'PARTITIONING',false);
Я думаю, что я также могу использовать REGEXP_REPLACE, но я тоже не знаю, как это сделать.
Для справки сгенерированный оператор содержит что-то вроде ниже:
...
SUPPLEMENTAL LOG GROUP "SCHEM_TAB0123434" ("CUSTOMERKEY", "VALID", "VERSION", "WHENMODIFIED") ALWAYS,
...
2 ответа
Я считаю, что SET_TRANSFORM_PARAM здесь не поможет.
Вы можете попробовать с REGEXP_REPLACE:
`v_stmt := regexp_replace(v_stmt, ',\s*supplemental\s+log\s+group\s+"[^"]+"\s*\("[^"]+"(,\s*"[^"]+")*\)\s*always\s*', '',1, 1,'i');`
Кажется, вы не можете полностью избавиться от него, но вы можете разделить дополнительные пункты журналирования на отдельные операторы и пропустить их, если вы используете разные dbms_metadata
Подпрограммы.
fetch_ddl
процедура дает вам вложенную таблицу отдельных операторов DDL; и вы можете объединить это с set_transform_param()
призыв вытащить ограничения как alter
заявления - что также относится к дополнительному пункту журнала. Вы также можете изменить имя таблицы как часть вызова выборки, а не заменять ее позже вручную, используя set_remap_param()
,
Если я создаю фиктивную таблицу с дополнительным ведением журнала:
create table t42 (
id number,
log_this varchar2(10),
constraint pk_t42 primary key (id),
supplemental log group t42_log_group (log_this) always
);
затем я могу открыть дескриптор контекста, применить фильтр для имени таблицы и преобразование; затем переберите DDL и выберите, что использовать и что пропустить:
set serveroutput on;
declare
l_original_table user_tables.table_name%type := 'T42';
l_new_table user_tables.table_name%type := 'NEW_T42';
l_context pls_integer;
l_modify pls_integer;
l_transform pls_integer;
l_ddls sys.ku$_ddls;
l_ddl clob;
begin
l_context := dbms_metadata.open('TABLE');
-- to look for the specific table you are interested in
dbms_metadata.set_filter(l_context, 'NAME', l_original_table);
l_modify := dbms_metadata.add_transform(l_context, 'MODIFY');
-- to change the table name in the generated DDL
dbms_metadata.set_remap_param(l_modify, 'REMAP_NAME', l_original_table, l_new_table,
'TABLE');
l_transform := dbms_metadata.add_transform(l_context, 'DDL');
-- for brevity
dbms_metadata.set_transform_param(l_transform, 'SEGMENT_ATTRIBUTES', false);
-- to split constraints and supplemental logging into separtate DDLs
dbms_metadata.set_transform_param(l_transform, 'CONSTRAINTS_AS_ALTER', true);
l_ddls := dbms_metadata.fetch_ddl(l_context);
for i in l_ddls.first..l_ddls.last loop
l_ddl := l_ddls(i).ddltext;
if dbms_lob.instr(l_ddl, 'SUPPLEMENTAL LOG GROUP') > 0 then
dbms_output.put_line('Skipping DDL: ' || dbms_lob.substr(l_ddl, 4000, 1));
continue;
end if;
dbms_output.put_line('Using DDL: ' || dbms_lob.substr(l_ddl, 4000, 1));
dbms_output.new_line;
-- execute immediate l_ddl;
end loop;
dbms_metadata.close(l_context);
end;
/
который для этой фиктивной таблицы показывает:
Using DDL: CREATE TABLE "MY_SCHEMA"."NEW_T42"
( "ID" NUMBER,
"LOG_THIS" VARCHAR2(10)
)
Using DDL:
ALTER TABLE "MY_SCHEMA"."NEW_T42" ADD CONSTRAINT "PK_T42" PRIMARY KEY ("ID")
USING INDEX ENABLE
Skipping DDL:
ALTER TABLE "MY_SCHEMA"."NEW_T42" ADD SUPPLEMENTAL LOG GROUP "T42_LOG_GROUP" ("LOG_THIS") ALWAYS
PL/SQL procedure successfully completed.
База create table
хранится вместе с любыми другими утверждениями, кроме тех, которые соответствуют 'SUPPLEMENTAL LOG GROUP'
строка.
В этом случае мое имя ограничения PK также будет проблемой - первое create
DDL будет работать с execute immediate
без комментариев, но alter
который в данный момент не пропущен, получит ORA-02264. Если у вас есть разумное соглашение об именах, вы можете добавить дополнительные set_remap_param
звонки, чтобы изменить их тоже, возможно.