Могу ли я использовать 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 звонки, чтобы изменить их тоже, возможно.

Другие вопросы по тегам