DBMS_METADATA パッケージは、データベースオブジェクトのメタデータを DDL 文または XML 形式で取得します。このパッケージを使用すると、オブジェクト定義の確認、オブジェクト再作成用スクリプトの生成、スキーマ変更の監査などが可能です。
プラグインのインストール
このパッケージに含まれる任意の関数を呼び出す前に、polar_dbms_metadata 拡張をインストールしてください:
CREATE EXTENSION IF NOT EXISTS polar_dbms_metadata;利用可能な関数
PolarDB では、Oracle の DBMS_METADATA パッケージの一部が実装されています。現在、以下の 1 つの関数がサポートされています:
| 関数 | 戻り値の型 | 説明 |
|---|---|---|
get_ddl | CLOB | 指定された名前の単一オブジェクトに対応する DDL 文を返します |
get_ddl
get_ddl 関数は、オブジェクトのタイプと名前を指定して、対応する DDL 文を取得します。インタラクティブな SQL 実行および単一オブジェクトの検索に適しています。
構文
FUNCTION get_ddl(
object_type IN VARCHAR2,
name IN VARCHAR2,
schema IN VARCHAR2 DEFAULT NULL,
version IN VARCHAR2 DEFAULT 'compatible',
model IN VARCHAR2 DEFAULT 'polardb',
transform IN VARCHAR2 DEFAULT 'ddl'
) RETURN CLOBパラメーター
| パラメーター | 必須 | 説明 |
|---|---|---|
object_type | はい | オブジェクトのタイプです。大文字・小文字を区別しません。サポートされる値については、「サポートされるオブジェクトタイプ」をご参照ください。 |
name | はい | オブジェクトの名前です。大文字・小文字を区別します。 |
schema | いいえ | オブジェクトを含むスキーマです。大文字・小文字を区別します。省略した場合は、現在のスキーマがデフォルトとなります。すべてのオブジェクトタイプに適用されるわけではなく、「サポートされるオブジェクトタイプ」をご参照ください。 |
version | いいえ | PolarDB for PostgreSQL(Oracle 互換)では無視されます。 |
model | いいえ | PolarDB for PostgreSQL(Oracle 互換)では無視されます。 |
transform | いいえ | PolarDB for PostgreSQL(Oracle 互換)では無視されます。 |
PolarDB for PostgreSQL(Oracle 互換)では、object_type、name、およびschemaのみが処理されます。version、model、transformの各パラメーターは Oracle 互換性のために受け付けられますが、実際には効果がありません。
パラメーターの大文字・小文字の区別
| パラメーター | 大文字・小文字を区別 | 例 |
|---|---|---|
object_type | いいえ | table、TABLE、Table のいずれも有効です |
name | はい | BIG_t と big_t は異なるオブジェクトとして扱われます |
schema | はい | public と PUBLIC は異なるスキーマとして扱われます |
返される DDL では、オブジェクト名およびスキーマ名は二重引用符で囲まれ、大文字・小文字が保持されます。
使用例
特定のスキーマ内のテーブルの DDL を取得する
テーブルを作成し、スキーマを明示的に指定して get_ddl を呼び出します:
CREATE TABLE t(a int, b text);
SELECT dbms_metadata.get_ddl('table', 't', 'public');出力:
get_ddl
---------------------------------------
CREATE TABLE IF NOT EXISTS public.t (+
a integer, +
b text COLLATE "default" +
) +
WITH (oids = true)
(1 row)スキーマを指定せずに DDL を取得する
対象オブジェクトが現在のスキーマ内にある場合、schema パラメーターを省略できます:
SELECT current_schema;current_schema
----------------
public
(1 row)SELECT dbms_metadata.get_ddl('table', 't');get_ddl
---------------------------------------
CREATE TABLE IF NOT EXISTS public.t (+
a integer, +
b text COLLATE "default" +
) +
WITH (oids = true)
(1 row)オブジェクトが別のスキーマ内にある場合の DDL 取得
現在のスキーマに該当オブジェクトが存在しない場合、schema パラメーターを省略すると -31603 エラーが発生します。この場合は、schema を明示的に指定してください:
-- 現在のスキーマを変更
SET search_path='';
-- スキーマを指定しない場合:失敗
SELECT dbms_metadata.get_ddl('table', 't');ERROR: Polar-31603: Object "t" of type "table" not found in schema "<NULL>"-- スキーマを指定した場合:成功
SELECT dbms_metadata.get_ddl('table', 't', 'public');get_ddl
---------------------------------------
CREATE TABLE IF NOT EXISTS public.t (+
a integer, +
b text COLLATE "default" +
) +
WITH (oids = true)
(1 row)`name` および `schema` の大文字・小文字の区別
大文字・小文字を混在させた識別子を持つテーブルを作成します:
CREATE TABLE public."BIG_t"("BIG_a" int, "BIG_b" text);object_type パラメーターは大文字・小文字を区別しません。「table」と「TABLE」のどちらでも動作します:
SELECT dbms_metadata.get_ddl('table', 'BIG_t', 'public');
SELECT dbms_metadata.get_ddl('TABLE', 'BIG_t', 'public');両方とも以下の結果を返します:
get_ddl
---------------------------------------------
CREATE TABLE IF NOT EXISTS public."BIG_t" (+
"BIG_a" integer, +
"BIG_b" text COLLATE "default" +
) +
WITH (oids = true)
(1 row)name および schema パラメーターは大文字・小文字を区別します。誤った大文字・小文字を使用するとエラーが発生します:
-- 名前の大文字・小文字が不正
SELECT dbms_metadata.get_ddl('table', 'big_t', 'public');ERROR: Polar-31603: Object "big_t" of type "table" not found in schema "public"-- スキーマの大文字・小文字が不正
SELECT dbms_metadata.get_ddl('table', 'BIG_t', 'PUBLIC');ERROR: Polar-31603: Object "BIG_t" of type "table" not found in schema "PUBLIC"サポートされるオブジェクトタイプ
以下のオブジェクトタイプがサポートされています。一部のタイプはスキーマに属さないため、詳細についてはスキーマ列をご確認ください。
| オブジェクトタイプ | スキーマの指定可否 |
|---|---|
| Table | はい |
| Index | はい |
| View | はい |
| Materialized view | はい |
| Function | はい |
| Stored procedure | はい |
| Constraint | はい |
| Trigger | いいえ |
| Tablespace | いいえ |
| Role | いいえ |
| User | いいえ(ロールと同様) |
スキーマを持たないオブジェクトタイプにおけるスキーマの動作
role および user の場合、スキーマを指定すると -31600 例外が発生します:
SET search_path TO public;
CREATE ROLE role1;
-- スキーマを指定しない場合:成功
SELECT dbms_metadata.get_ddl('role', 'role1');get_ddl
-------------------------------------------
CREATE ROLE role1 WITH +
NOSUPERUSER NOCREATEDB NOCREATEROLE +
INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS+
CONNECTION LIMIT -1 PASSWORD NULL
(1 row)-- スキーマを指定した場合:-31600 例外が発生
SELECT dbms_metadata.get_ddl('role', 'role1', 'public');ERROR: Polar-31600: Invalid input value "public" for parameter SCHEMA in function get_ddl
DETAIL: No need to specify schema for type ROLE/USERtrigger の場合、スキーマを指定すると警告が表示されますが、例外は発生しません。指定されたスキーマ値は無視され、結果が返されます:
CREATE TABLE t (id int, name varchar(10));
CREATE OR REPLACE FUNCTION print_insert()
RETURNS TRIGGER AS $$
BEGIN
RAISE NOTICE 'INSERT: %', NEW.id;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger1 after INSERT ON public.t FOR EACH row EXECUTE PROCEDURE print_insert();
SELECT dbms_metadata.get_ddl('trigger', 'trigger1', 'public');WARNING: No need to specify schema for trigger, ignore it.
get_ddl
-------------------------------------------------------------------------------------------------------
CREATE TRIGGER trigger1 AFTER INSERT ON public.t FOR EACH ROW EXECUTE PROCEDURE public.print_insert()
(1 row)例外
get_ddl 関数は 2 種類の例外を発生させます。例外コードは Oracle と一致しており、メッセージ内容もほぼ同一です。
| コード | 条件 | 例(メッセージ) |
|---|---|---|
| -31600 | 無効なオブジェクトタイプ、空のオブジェクトタイプ、空のオブジェクト名、またはスキーマを持たないオブジェクトタイプに対してスキーマが指定された場合 | Polar-31600: Invalid input value "public" for parameter SCHEMA in function get_ddl |
| -31603 | オブジェクトが見つからない場合 | Polar-31603: Object "t" of type "table" not found in schema "<NULL>" |
上記の 2 種類の例外のみがサポートされています。その他の Oracle の例外タイプは実装されていません。