オブジェクトに対しメタデータをフェッチする場合、そのメタデータを使用して、オブジェクトを異なるデータベースまたはスキーマで再作成することがあります。
メタデータをフェッチする際に、再マップの実行を決定していない場合もあります。また、この決定を先送りにしたい場合があります。再マップを先送りにするには、メタデータをXMLとしてフェッチし、ファイルまたは表に格納します。後で送信インタフェースを使用しオブジェクトを再作成します。
送信インタフェースは取得インタフェースに類似した構成です。送信インタフェースには、作成するオブジェクトのオブジェクト型を指定するOPENWプロシージャが存在します。変換の指定、パラメータの変換および項目の解析ができます。CONVERTファンクションをコールしてXMLからDDLに変換する、またはPUTファンクションをコールしてXMLをDDLに変換し、DDLを送信してオブジェクトを作成できます。
関連項目:
送信インタフェースで使用するDBMS_METADATAプロシージャおよびファンクションの詳細は、表21-3を参照してください。
例21-7は、1つのスキーマの表のXMLをフェッチし、次に送信インタフェースを使用して別のスキーマの表を再作成します。
例21-7 取得したオブジェクトを再作成するための送信インタフェースの使用
次のように、権限を持つユーザーとして接続します。
CONNECT system
Enter password: password
実行者権限パッケージを作成してプロシージャを保持します。これは、別のスキーマ内のオブジェクトにアクセスするには、SELECT_CATALOG_ROLEロールが必要なためです。定義者権限PL/SQLオブジェクト(プロシージャ、ファンクションなど)では、ロールは使用できません。
CREATE OR REPLACE PACKAGE example_pkg AUTHID current_user IS
PROCEDURE move_table(
table_name in VARCHAR2,
from_schema in VARCHAR2,
to_schema in VARCHAR2 );
END example_pkg;
/
CREATE OR REPLACE PACKAGE BODY example_pkg IS
PROCEDURE move_table(
table_name in VARCHAR2,
from_schema in VARCHAR2,
to_schema in VARCHAR2 ) IS
-- Define local variables.
h1 NUMBER; -- handle returned by OPEN
h2 NUMBER; -- handle returned by OPENW
th1 NUMBER; -- handle returned by ADD_TRANSFORM for MODIFY
th2 NUMBER; -- handle returned by ADD_TRANSFORM for DDL
xml CLOB; -- XML document
errs sys.ku$_SubmitResults := sys.ku$_SubmitResults();
err sys.ku$_SubmitResult;
result BOOLEAN;
BEGIN
-- Specify the object type.
h1 := DBMS_METADATA.OPEN('TABLE');
-- Use filters to specify the name and schema of the table.
DBMS_METADATA.SET_FILTER(h1,'NAME',table_name);
DBMS_METADATA.SET_FILTER(h1,'SCHEMA',from_schema);
-- Fetch the XML.
xml := DBMS_METADATA.FETCH_CLOB(h1);
IF xml IS NULL THEN
DBMS_OUTPUT.PUT_LINE('Table ' || from_schema || '.' || table_name
|| ' not found');
RETURN;
END IF;
-- Release resources.
DBMS_METADATA.CLOSE(h1);
-- Use the submit interface to re-create the object in another schema.
-- Specify the object type using OPENW (instead of OPEN).
h2 := DBMS_METADATA.OPENW('TABLE');
-- First, add the MODIFY transform.
th1 := DBMS_METADATA.ADD_TRANSFORM(h2,'MODIFY');
-- Specify the desired modification: remap the schema name.
DBMS_METADATA.SET_REMAP_PARAM(th1,'REMAP_SCHEMA',from_schema,to_schema);
-- Now add the DDL transform so that the modified XML can be
-- transformed into creation DDL.
th2 := DBMS_METADATA.ADD_TRANSFORM(h2,'DDL');
-- Call PUT to re-create the object.
result := DBMS_METADATA.PUT(h2,xml,0,errs);
DBMS_METADATA.CLOSE(h2);
IF NOT result THEN
-- Process the error information.
FOR i IN errs.FIRST..errs.LAST LOOP
err := errs(i);
FOR j IN err.errorLines.FIRST..err.errorLines.LAST LOOP
dbms_output.put_line(err.errorLines(j).errorText);
END LOOP;
END LOOP;
END IF;
END;
END example_pkg;
/
ここで、次のように、スキーマSCOTTでmy_exampleという名前の表を作成します。
CONNECT scott
Enter password:
-- The password is tiger.
DROP TABLE my_example;
CREATE TABLE my_example (a NUMBER, b VARCHAR2(30));
CONNECT system
Enter password: password
SET LONG 9000000
SET PAGESIZE 0
SET SERVEROUTPUT ON SIZE 100000
次のように、my_example表をSYSTEMスキーマにコピーします。
DROP TABLE my_example;
EXECUTE example_pkg.move_table('MY_EXAMPLE','SCOTT','SYSTEM');
次の問合せを実行して、正しく動作したことを確認します。
SELECT DBMS_METADATA.GET_DDL('TABLE','MY_EXAMPLE') FROM dual;