2015-11-24 157 views
13

我正在創建一個包來生成架構中的對象的DDL(您解析對象名稱,並返回一個帶有DDL的clob),所以我可以生成文件並將他們直接進入SVN。如何使dbms_metadata.get_ddl更漂亮/更有用

我使用的是dbms_metadata.get_ddl,它適用於除表格/物化視圖以外的所有對象。

如果我創建一個表:

create table stackoverflow 
    (col_1 varchar2(64) 
    , col_2 number 
    , col_3 date); 

create index idx_test on stackoverflow(col_1); 

alter table stackoverflow add constraint ui_test unique (col_2) using index; 

併產生DDL:

begin 
    dbms_output.put_line(dbms_metadata.get_ddl(object_type => 'TABLE' 
              , name => 'STACKOVERFLOW') 
         ); 
end; 

它給了我們:

CREATE TABLE "TEST_SCHEMA"."STACKOVERFLOW" 
( "COL_1" VARCHAR2(64), 
    "COL_2" NUMBER, 
    "COL_3" DATE, 
    CONSTRAINT "UI_TEST" UNIQUE ("COL_2") 
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) 
TABLESPACE "USERS_DATA_TS" ENABLE 
) 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 DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
TABLESPACE "USERS_DATA_TS" 

採取一切相關的指標,我們可以使用:

begin 
    dbms_output.put_line(dbms_metadata.get_dependent_ddl(object_type => 'INDEX' 
                 , base_object_name => 'STACKOVERFLOW')); 
end; 

有:

CREATE INDEX "TEST_SCHEMA"."IDX_TEST" ON "MF"."STACKOVERFLOW" ("COL_1") 
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) 
TABLESPACE "USERS_DATA_TS" 
CREATE UNIQUE INDEX "TEST_SCHEMA"."UI_TEST" ON "MF"."STACKOVERFLOW" ("COL_2") 
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) 
TABLESPACE "USERS_DATA_TS" 

我想創建一個包含文件:創建表,約束,索引,授權(有一個文件所需要的所有定義),並使用dbms_metadata它看起來不可能的,我做的。

我與輸出的問題是:這個名字

  • 架構名稱的DDL內

    1. 雙引號使我們難以在許多架構編譯相同DDL。爲了解決這個問題,我們需要創建一些對正則表達式或添加像下面這樣可以解決這個問題:

      dbms_metadata.SET_REMAP_PARAM(dbms_metadata.SESSION_TRANSFORM,'REMAP_SCHEMA','TEST_SCHEMA',''); 
      

      ,但你必須添加像8個行:

      hOpenOrig0 := DBMS_METADATA.OPEN('TABLE'); 
      DBMS_METADATA.SET_FILTER(hOpenOrig0,'NAME',p_object_name); 
      DBMS_METADATA.SET_FILTER(hOpenOrig0,'SCHEMA',get_table.owner); 
      tr := dbms_metadata.add_transform(hOpenOrig0, 'MODIFY'); 
      hTransDDL := DBMS_METADATA.ADD_TRANSFORM(hOpenOrig0,'DDL'); 
      dbms_metadata.set_remap_param(tr, name => 'REMAP_SCHEMA', old_value => user, new_value => ''); 
      get_package_spec.ddl := DBMS_METADATA.FETCH_CLOB(hOpenOrig0); 
      DBMS_METADATA.CLOSE(hOpenOrig0); 
      
    2. 沒有辦法在同一時刻提取約束(使用索引)和索引。由於重複定義ui_test,您無法連接輸出。是的,您可以選擇從get_ddl中刪除約束條件,但我們正在失去約束/檢查。

    3. 如何在PL/SQL開發人員創建的輸出

      -- Create table 
      create table STACKOVERFLOW 
      (
          col_1 VARCHAR2(64), 
          col_2 NUMBER, 
          col_3 DATE 
      ) 
      tablespace USERS_DATA_TS 
          pctfree 10 
          pctused 40 
          initrans 1 
          maxtrans 255 
          storage 
          (
          initial 128K 
          next 128K 
          minextents 1 
          maxextents unlimited 
          pctincrease 0 
      ); 
      -- Create/Recreate indexes 
      create index IDX_TEST on STACKOVERFLOW (COL_1) 
          tablespace USERS_DATA_TS 
          pctfree 10 
          initrans 2 
          maxtrans 255 
          storage 
          (
          initial 128K 
          next 128K 
          minextents 1 
          maxextents unlimited 
          pctincrease 0 
      ); 
      -- Create/Recreate primary, unique and foreign key constraints 
      alter table STACKOVERFLOW 
          add constraint UI_TEST unique (COL_2) 
          using index 
          tablespace USERS_DATA_TS 
          pctfree 10 
          initrans 2 
          maxtrans 255 
          storage 
          (
          initial 128K 
          next 128K 
          minextents 1 
          maxextents unlimited 
          pctincrease 0 
      ); 
      

    是否有人知道的方式來創建一個類似於PL/SQL開發人員輸出?我想他們創建了一些dbms_metadata.get_xml的XML解析器)來創建一個更漂亮的版本(縮進,順序,所有這些都在好的地方,隨時可以編譯)。

    當然,我可以玩正則表達式或user_indexes,但那不是重點。

    ps。 DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'PRETTY',true);是一個奇怪的定義什麼是「漂亮」。

  • +0

    您可以刪除使用dbms_metadata.set_transform_param架構前綴發現 - 有一個標誌,不顯示或重新映射架構TEST_SCHEMA爲null。 PL/SQL Developer不使用dbms_metadata來生成ddl,所以沒有引號。 – thatjeffsmith

    回答

    -2

    我可以建議你爲ddl導出目的使用expdp/impdp。

    導出架構:faydin以下expdp。在ddl.sqluser : faydin remapped as: faydin3

    expdp userid=faydin/***** directory=ORA_TMP_DIR reuse_dumpfiles=y content=METADATA_ONLY exclude=STATISTICS schemas=faydin dumpfile=metadata.dmp

    獲取DDL與IMPDP

    impdp userid=faydin/***** directory=ORA_TMP_DIR dumpfile=metadata.dmp sqlfile=ddl.sql remap_schema=faydin:faydin3

    導入模式通過刪除IMPDP命令sqlfile=ddl.sql短語分貝。

    7

    dbms_metadata.get_dll將oracle對象作爲xml獲取,然後通過xslt將其轉換爲ddl腳本。

    有用表的列表select table_name from all_tables where table_name like 'META%'

    1. METASTYLESHEET - 圖樣式表來它的名字

    2. METAXSL $ - 地圖中XMLTAG樣式表的名字 - 鏈接這第一臺

    3. METAVIEW $ - 對象類型映射到一個XMLTAG - 將其鏈接到第二個表
    4. METAXSLPARAM $ - 可用於每種對象類型和變換類型的變換過濾器的查找表。

    對於表Oracle使用kutable對XML到DDL的指數Oracle使用kuindex ...等

    通過設置參數,你可以改變轉型的行爲。要查找有用的參數,請檢查METAXSLPARAM $ table或在樣式表文檔中進行搜索。 EMIT_SCHEMA - 我在kucommon XSLT

    EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'EMIT_SCHEMA',false); --undocumented remove schema 
    EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SEGMENT_CREATION',false); --undocumented remove segement creation 
    EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'CONSTRAINTS_AS_ALTER',true); 
    select dbms_metadata.get_ddl(object_type => 'TABLE' , name => 'STACKOVERFLOW') from dual; 
    
    +0

    真的很有幫助。當然,它解決了我使用'regexp'修復的部分問題('EMIT-SCHEMA')... 它並不能完全解決我的問題,但我會研究所有參數 –

    +0

    不幸的是,有趣的排放模式...調查更多我發現更多的問題與get_dll ...我想我將不得不提高一些票直接到甲骨文 –

    +0

    還請注意'SEGMENT_CREATION'似乎不再可用與12i(扔這裏有錯誤)。此外,我錯過了使用'get_ddl'的'COMMENT ON' - 並且它使用'CONSTRAINTS_AS_ALTER'生成了多個語句('CREATE TABLE' ...'ALTER TABLE'),但沒有正確分離(沒有找到一個分號)。是否還有其他參數丟失,如'dbms_metadata.set_transform_param(dbms_metadata.session_transform,'SQLTERMINATOR',true);'? ;) – Izzy