Poďme na to. Mnohí hlavne začiatočníci by si mali naštudovať pri programovaní v PL/SQL aj množstvo užitočných balíkov (packages), ktorými sa dajú robiť užitočné veci ako napríklad, prečítať a generovať/ celé komplexné DDL príkazy jednotlivých objektov, vygenerovať "explain plan" pre SQL príkazy, spustiť tuningovanie SQL príkazov, pracovať so súbormi, s FTP, SMTP protokolmi atď, atď.
Dnes som si vybral možno si poviete jednoduchú vec. Áno, je to jednoduchá vec, stačí napísať SQL príkaz:
SELECT DBMS_LOB.SUBSTR(DBMS_METADATA.GET_DDL('TABLE','MENO_TABULKY','MENO_SCHEMY'), 4000, 1) FROM DUAL;
Na obrazovke máme vypísaný kompletný DDL príkaz na vytvorenie tabuľky 'MENO_TABULKY' nachádzajúcej sa v schéme 'MENO_SCHEMY'. Analogicky po vyplnení parametrov napr. pre index sa v schéme zobrazí DDL kód pre vytvorenie indexu v danej schéme. Problém avšak nastane, keď požadujeme vygenerovanie DDL príkazu, ktorý ma viac ako 4000B. Ako vieme, v DML - "SELECT" príkaze hodnota stĺpca pre typ VARCHAR2 nesmie presiahnúť hodnotu 4000B alebo znakov (podľa nastavenia semantiky). V tomto prípade si poradíme napríklad vypísaním takéhoto DDL príkazu rovno na výstup pekne po riadkoch. Vypýtame si DDL kód z metadát schémy a budeme čítať a vypisovať jednotlivé riadky DDL príkazu (Predpokladáme, že riadok nepresiahne dĺžku 1000 znakov, kôli funkcii DBMS_OUTPUT.PUT_LINE. Ak by presahoval, je potrebné doprogramovať ďalší cyklus na ešte podrobnejší výpis riadkov.) do výstupu.
Predpokladám, že programátor už má základé znalosti programovania v PL/SQL. Príklad som testoval na databáze Oracle 11g R2 bežiacej na 64b WIN 2008.
Pripojíme sa na databázu a jednoducho spustítme tento anonymný blok:
SET SERVEROUTPUT ON -- v prostredí klienta Toad DECLARE CRLF CONSTANT VARCHAR2(5) := CHR(10); H NUMBER := NULL; TH NUMBER; DDL_LIST sys.ku$_ddls; DDL CLOB; A INTEGER; B INTEGER; J INTEGER; BEGIN -- specify the object type: TABLEs H := DBMS_METADATA.OPEN('TABLE'); -- specify schema MENO_SCHEMY DBMS_METADATA.SET_FILTER(h,'SCHEMA','MENO_SCHEMY'); -- specify the table named: MENO_TABULKY DBMS_METADATA.SET_FILTER(h,'NAME','MENO_TABULKY'); -- request that the metadata be transformed into creation DDL TH := DBMS_METADATA.ADD_TRANSFORM(H,'DDL'); -- Fetch the object. LOOP --DDL_LIST := DBMS_METADATA.FETCH_CLOB(h); -- get the DDL list DDL_LIST := DBMS_METADATA.FETCH_DDL(H); -- finish the loop if any DDL commands were listed EXIT WHEN DDL_LIST IS NULL; -- loop the DDL FOR I IN DDL_LIST.FIRST..DDL_LIST.LAST LOOP DDL := DDL_LIST(I).ddlText; --DBMS_OUTPUT.PUT_LINE(TO_CHAR(I)||' - '||DDL); IF DBMS_LOB.GETLENGTH(DDL) > 0 THEN J := 0; LOOP IF J = 0 THEN A := 1; B := DBMS_LOB.INSTR (DDL, CRLF, 1, 1); ELSE A := DBMS_LOB.INSTR (DDL, CRLF, 1, J); EXIT WHEN A = 0; B := DBMS_LOB.INSTR (DDL, CRLF, 1, J + 1); END IF; IF B = 0 THEN B := DBMS_LOB.GETLENGTH(DDL); END IF; -- write DDL line to the output DBMS_OUTPUT.PUT_LINE(DBMS_LOB.SUBSTR(DDL, B - A + 1, A)); J := J + 1; END LOOP; END IF; END LOOP; END LOOP; -- release resources DBMS_METADATA.CLOSE(H); EXCEPTION WHEN OTHERS THEN IF H IS NOT NULL THEN DBMS_METADATA.CLOSE(H); END IF; END;
Hotovo, na obrazovke máme vypísaný kód DDL príkazu požadovaného objektu, v mojom prípade tabuľky "MENO_TABULKY" v schéme "MENO_SCHEMY". Využil som balík DBMS_METADATA na získanie metadát, ďalej balík DBMS_LOB pre prácu s CLOB objektami (reťazcami, ktoré môžu presiahnuť dĺžku 32000 znakov) a balíku DBMS_OUTPUT a to funkciu na výpis dát do bufferu PUT_LINE. Verím, že tento kúsok PL/SQL kódu bude nápomocný všetkým.
S pozdravom AB