2016年5月4日水曜日

[Oracle]DBMS_ASSERT.QUALIFIED_SQL_NAMEと修飾SQL名

目的

Oracleの勉強をしていて、修飾SQL名とは何かがわからなくて検索するも、よい回答がなかったので、ここでまとめる。

修飾SQL名とは何か

修飾SQL名とは、以下の3つを表す文字列のことである。

  • ローカル修飾SQL名
  • データベースリンク名
  • 接続文字列

ローカル修飾SQL名

単純SQL名と"."(ドット)で構成される文字列。 下記に示す文字列は、ローカル修飾SQL名である。

  • 'tbl_name'(テーブル名)
  • 'column_name'(カラム名)
  • 'tbl_name.column_name'(テーブル名.カラム名)
  • 'pkg_name.fun_name'(パッケージ.ファンクション名) ... etc

Oracleの厳密な定義は以下

  • <ローカル修飾SQL名> ::= <単純SQL名> {'.' <単純SQL名>}

単純SQL名とは、Oracleのオブジェクトを表す文字列と二重引用符で囲まれた文字列のことで、 オブジェクトを表す文字列とは

  • 頭文字は英字のみ
  • 2文字目以降は英数字、アンダーバー、ドルマーク、シャープがOK
  • 30文字以下
のこと。

データベースリンク名

@が付いている文字列で、他のデータベースへのアクセスを容易にするもの。

下記に示す文字列がデータベースリンクである

  • 'tbl_name.column_name@dblink'

Oracleの厳密な定義は以下

  • <データベースリンク名> ::= <ローカル修飾SQL名> ['@' <接続文字列>]

接続文字列

データベースリンクを貼りたい接続先の接続名。

Oracleの定義では単純SQL名のみOKだが、ローカル修飾SQL名を満たせばOKのような感じ。]

Oracleの厳密な定義は以下

  • <接続文字列> ::= <単純SQL名>

DBMS_ASSERT.QUALIFIED_SQL_NAMEを試した結果(ソース)

下記に少しだけQUALIFIED_SQL_NAMEを試したソースを載せておきます。
DECLARE
    v_test  VARCHAR2(1000) := NULL;
    
    PROCEDURE TEST( in_str VARCHAR2, in_test VARCHAR2 )
    IS
        v_ret VARCHAR2(1000) := NULL;
    BEGIN
        DBMS_OUTPUT.PUT_LINE(' ===== ' || in_str || ' ===== ');
        BEGIN
            v_ret := DBMS_ASSERT.QUALIFIED_SQL_NAME(in_test);
            DBMS_OUTPUT.PUT_LINE('v_ret:' || v_ret);
        EXCEPTION
            WHEN OTHERS THEN
                DBMS_OUTPUT.PUT_LINE('SQLCODE:' || SQLCODE);
                DBMS_OUTPUT.PUT_LINE('SQLERRM:' || SQLERRM);
        END;
    END;
BEGIN
    -- 単純SQL名
    v_test := 'TM01_LASTDEGREE';
    TEST( 'test1', v_test );
    
    -- ローカル修飾SQL名
    v_test := 'TM01_LASTDEGREE.LASTDEGREE';
    TEST( 'test2', v_test );
    
    -- 空
    v_test := '';
    TEST( 'test3', v_test );

    -- 接続文字列
    v_test := 'User Id=scott;Password=tiger;Data Source=oracle';
    TEST( 'test4', v_test );

    -- 接続文字列
    v_test := 'dbhost.example.com';
    TEST( 'test5', v_test );
    
END;