Blog programisty w Oracle PL/SQL

Jest to blog eksperymentatora programisty w PL/SQL dla Oracle. Wszystkie kody tutaj zamieszczone mogą być dowolnie wykorzystywane i zmieniane. A jeśli Ktoś z Gości znajdzie błąd, będę niezwykle wdzięczny...
Zapisz

Szukaj na tym blogu

środa, 13 kwietnia 2011

DBMS_METADATA - generowanie skryptów DDL

Bardzo ciekawym pakietem dostarczonym z bazą danych jest DBMS_METADATA – jego głównym zadaniem jest tworzenie skryptów DDL dla różnych obiektów bazodanowych..

Dokumentacji nie będę przepisywać, ale przedstawię kilka zastosowań

Należy zauważyć, że wywołania w instrukcjach SQL umożliwiają ograniczone możliwości wykorzystania API, skrypty PL/SQL pozwalają na bardziej zaawansowane mozliwości tworzenia skryptów DDL

  • Skrypt do tworzenia listy uprawnień dla bieżącego użytkownika:
SELECT
DBMS_METADATA.GET_GRANTED_DDL('ROLE_GRANT', USER)
            ||
DBMS_METADATA.GET_GRANTED_DDL('SYSTEM_GRANT', USER)
            ||
DBMS_METADATA.GET_GRANTED_DDL('OBJECT_GRANT', USER)
FROM DUAL
  • Skrypt do tworzenia indeksów w bieżącym schemacie
SELECT DBMS_METADATA.GET_DDL('INDEX', INDEX_NAME, USER) ||';' FROM USER_INDEXES WHERE VISIBILITY = 'VISIBLE'
  • Skrypt do tworzenia bieżącego użytkownika
SELECT DBMS_METADATA.GET_DDL('USER', USER)
FROM DUALpod warunkiem, że użytkownik nie jest SYS/SYSDBA
  • Przeniesienie tabel  ze schematu SOURCE_SCHEMA  do schematu DESTINATION_SCHEMA wszystkich z tabel z nazwami zaczynającymi się na B, z pominięciem atrybutów storage i  kluczy obcych…
zacznijmy od  stworzenia tabeli na wynikowy skrypt
CREATE  TABLE TBL_DDL_DATA(
DDL_SCRIPT CLOB DEFAULT EMPTY_CLOB()
);

poniżej skrypt
DECLARE
v_hdl NUMBER;
v_th1 NUMBER;
v_th2 NUMBER;
v_doc sys.ku$_ddls := sys.ku$_ddls();
   BEGIN
      delete from T_BLOB;
      v_hdl := DBMS_METADATA.OPEN('TABLE', 'LATEST');
      DBMS_METADATA.SET_FILTER (v_hdl,'SCHEMA_EXPR','
IN( ''SOURCE_SCHEMA'')');
      DBMS_METADATA.SET_FILTER (v_hdl,'NAME_EXPR','LIKE ''B%''');
      v_th1 := DBMS_METADATA.ADD_TRANSFORM (v_hdl,'MODIFY', NULL, 'TABLE');
      DBMS_METADATA.SET_REMAP_PARAM(v_th1,'REMAP_SCHEMA', 'SOURCE_SCHEMA', 'DESTINATION_SCHEMA');
      v_th2:=DBMS_METADATA.ADD_TRANSFORM(v_hdl,'DDL');
      DBMS_METADATA.SET_TRANSFORM_PARAM(v_th2,    'SQLTERMINATOR', TRUE);
DBMS_METADATA.SET_TRANSFORM_PARAM(v_th2,    'SEGMENT_ATTRIBUTES', FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM(v_th2,'REF_CONSTRAINTS', FALSE, 'TABLE');
DBMS_OUTPUT.PUT_LINE(DBMS_METADATA.GET_QUERY(v_hdl));
LOOP
   
    v_doc := DBMS_METADATA.FETCH_DDL(v_hdl);
    IF v_doc IS NOT EMPTY THEN
        IF v_doc.COUNT >0 THEN
            INSERT INTO TBL_DDL_DATA(DDL_SCRIPT)
            VALUES (v_doc(v_doc.last).DDLTEXT);
        END IF;
    END IF;
EXIT
WHEN v_doc IS NULL;
END LOOP;
COMMIT; 
DBMS_METADATA.CLOSE(v_hdl);
END;

Jeśli chcemy wykonać skrypt, zaleca się posiadać rolę CREATE TABLE do schematu docelowego

Moje uwagi:
  • z poziomu SQL nie ma możliwości parametryzacji skryptów - pominięcia parametrów storage, ustawienia filtra, zmiany schematu - to wszystko można zrobić w PL/SQL
  • Skrypty  dla lokalnych dla tabeli partycjonowanych działają dobrze pod warunkiem, że owe tabele są puste(zgodnie z założeniem pakiety – tworzenie  struktur, a nie ich rozbudowywanie)
  • Skrypty DDL dla tabel partycjonowanych  interwałowo niekiedy są generowane błędnie
  • Dłuższe skrypty opłaca się zapisywać do pól CLOB
  • Pakiet jest dość powolny


Brak komentarzy:

Prześlij komentarz