モジュール内で定義されたオブジェクトの参照

モジュールに定義されたオブジェクトの参照は、モジュールの内外から行うことができます。 またモジュールに定義されたオブジェクトを参照できるかどうかは、モジュール内のオブジェクトがパブリッシュされているかどうかに依存しています。

モジュール・オブジェクトは、3 つの部分からなる名前、2 つの部分からなる名前、場合によっては 1 つの部分からなる名前によって参照できます。 名前参照の解決は決定論的に行われ、使用されている名前参照とコンテキスト (モジュールの内外) によって異なります。

  • モジュール内からの場合:
    • パブリッシュ済みモジュール・オブジェクトであれ、非公開モジュール・オブジェクトであれ、モジュール内で定義されたオブジェクトは、3 つの部分、2 つの部分、および 1 つの部分からなる名前参照を使用して参照できます。
  • モジュール外からの場合:
    • パブリッシュ済みモジュール・オブジェクトのみが、3 つの部分および 2 つの部分からなる名前参照を使用して参照可能です。

3 つの部分からなる名前参照のオブジェクト解決

3 つの部分からなる名前参照は、最も簡単です。<SCHEMA-NAME>.<MODULE-NAME>.<OBJECT-NAME> という形式です。 このタイプの参照は、固有のモジュール・オブジェクトに必ず解決されます。

以下は、schema という名前のスキーマの mod というモジュールの定義です。
CREATE MODULE schema.mod@

ALTER MODULE schema.mod 
  PUBLISH PROCEDURE proc1 (a integer) 
            BEGIN
            END@

以下は、3 つの部分からなる名前参照を使用してプロシージャーを参照する CALL ステートメントの例です。

CALL schema.mod.proc1@ 
次の組み込み例では、3 つの部分からなる名前を使用してストアード・プロシージャーを呼び出しています。
// Assume that the  server has following package and procedure defined
CREATE OR REPLACE PACKAGE MyPackage IS
  PROCEDURE MyProcedure(INOUT a INTEGER);
END;

CREATE OR REPLACE PACKAGE BODY MyPackage IS
  PROCEDURE MyProcedure(INOUT a INTEGER) IS
    a := a + 100;
  END;
END;

// Embedded SQL C program snippet
EXEC SQL BEGIN DECLARE SECTION;
  sqlint32 inout_val;
EXEC SQL END DECLARE SECTION;

EXEC SQL CALL MySchema.MyPackage.MyProcedure(:inout_val);

2 つの部分からなる名前参照のオブジェクト解決

2 つの部分からなる名前参照の形式は、<MODULE-NAME>.<OBJECT-NAME> です。

2 つの部分からなる名前参照形式は紛らわしい場合があります。非モジュール・オブジェクトの場合、2 つの部分からなる <SCHEMA-NAME>.<OBJECT-NAME> という形式で参照できるからです。最初の修飾子は、スキーマまたはモジュールのいずれかを参照できます。 2 つの部分からなる名前参照を解決する決定論的なメソッドは、以下のようにしてオブジェクト参照を解決します。
  • 参照するコンテキストがモジュール内にあり、修飾子の最初の部分がモジュール名と一致する場合、データベース・マネージャーはパブリッシュ済みおよびパブリッシュされていないモジュール・オブジェクトで一致するものを見つけるために、オブジェクトのタイプに関する適切な解決方法を適用して、モジュール内を検索してオブジェクトを探します。 一致するものが見つからないと、次の箇条書き (黒丸) で指定されているように検索を続行します。
  • 次に、2 つの部分からなる名前参照の最初の部分がスキーマ名であると想定されます。 そのような名前のスキーマが存在する場合、オブジェクトはそのスキーマ内で解決されます。
  • 2 つの部分からなる名前参照の最初の部分が既存のスキーマでないか、修飾子が一致するスキーマ内にオブジェクトがなく、修飾子がコンテキスト・モジュール名と一致しなかった場合、SQL パスにあるスキーマ内の修飾子と一致する最初のモジュールが検索されます。 一致するモジュールに対する権限がある場合には、そのモジュール内のオブジェクトに解決されますが、対象となるのはパブリッシュ済みモジュール・オブジェクトだけです。
  • 修飾子が SQL パス上のモジュールとして検出されず、修飾子がコンテキスト・モジュール名と一致しなかった場合、その修飾子と一致するモジュールのパブリック・シノニムを調べます。 もし見つかれば、そのモジュールのパブリック・シノニムによって識別されるモジュール内のオブジェクトに解決されますが、対象となるのはパブリッシュ済みモジュール・オブジェクトだけです。
以下の SQL ステートメントは、複数のモジュール・オブジェクトと、モジュール・オブジェクトへの参照を定義します。 コメントにより、それぞれ 2 つの部分からなるオブジェクト名参照がどのモジュール・オブジェクトに解決されるかが示されています。
CREATE PROCEDURE S.proc1 (a integer) 
        BEGIN END@

CREATE MODULE schema.S@

ALTER MODULE schema.S 
  PUBLISH PROCEDURE proc1 (a integer) 
            BEGIN END@

CALL S.proc1(5)@ 								-- This reference resolves to procedure S.proc1()

ALTER MODULE schema.S 
  PUBLISH PROCEDURE proc2 (a integer) 
            BEGIN
              CALL S.proc1(5)		-- This reference resolves to procedure schema.S.proc1()
            END@

CREATE MODULE schema.M@

ALTER MODULE schema.M 
  PUBLISH PROCEDURE proc1 (a integer) 
            BEGIN END@

CALL M.proc1(5)@ 				         -- This reference resolves to procedure schema.M.proc1()

1 つの部分からなる名前参照のオブジェクト解決

1 つの部分からなる名前参照は、モジュールのコンテキスト内にあるモジュール・オブジェクトにのみ使用できます。 モジュール内のオブジェクトのみが、1 つの部分からなる名前参照を使用して別のモジュール・オブジェクトを参照できます。

以下に、1 つの部分からなるオブジェクト名前参照の決定論的な解決方法について定義します。
  • 参照するコンテキストがモジュール内にある場合、タイプが一致するオブジェクトを見つけるためにモジュール内で検索が行われます。 1 つの部分からなる名前参照で一致するものが見つからない場合、対象のオブジェクトはモジュール・オブジェクトではなく、スキーマ・オブジェクトであると想定されます。 SQL パス内の最初のスキーマに関して SQL パスが検索され、スキーマに適切なタイプのオブジェクトが存在するか検査されます。 そのようなオブジェクトが見つからないと、名前参照の解決が失敗します。
  • 以下の SQL ステートメントは、オブジェクト、モジュール、およびモジュール・オブジェクトを定義しています。コメントによって、そのうちのどれであるかが示されています。
CREATE PROCEDURE S.proc1 (a integer) 
         BEGIN
         END@

CREATE MODULE schema.S@

ALTER MODULE schema.S 
  PUBLISH PROCEDURE proc1 (a integer) 
    BEGIN
    END@

CALL proc1(5)@ 				-- will resolve to S.proc1()

ALTER MODULE schema.S 
  PUBLISH PROCEDURE proc2 (a integer) 
            BEGIN
              CALL proc1(5)			-- will resolve to schema.S.proc1()
            END@

CREATE MODULE schema.M@

ALTER MODULE schema.M 
  PUBLISH PROCEDURE proc1 (a integer) 
            BEGIN
              CALL proc1(5)			-- will resolve to S.proc1()
                                  -- (since no proc1() in module M)
            END@