パッケージで NUMBER 型を返す関数を作成しましたが、パッケージ仕様でこの関数を宣言していません。
同じパッケージ本体で別の関数の SQL クエリでこの関数を呼び出しています。エラーが発生しています。
パッケージ仕様で関数を宣言すると、うまく機能します。
その背後にある理由を知りたい。誰か説明してください。
パッケージで NUMBER 型を返す関数を作成しましたが、パッケージ仕様でこの関数を宣言していません。
同じパッケージ本体で別の関数の SQL クエリでこの関数を呼び出しています。エラーが発生しています。
パッケージ仕様で関数を宣言すると、うまく機能します。
その背後にある理由を知りたい。誰か説明してください。
前方宣言とはまったく関係ありません。
これは、関数を呼び出すために SQL クエリを使用しているという事実を扱います。ステートメントを使用して関数を呼び出すと、PL/SQL パッケージのスコープ内にいなくなるため、公開されている関数のみを呼び出すことができるようです。
その理由については推測でしかありませんので、当然とは思わないでください。ただし、PL/SQL と SQL ではエンジンが異なります。したがって、SQL クエリを実行するときは、pl/sql パッケージ内であっても、SQL エンジンに従って権限を再度チェックする SQL のレベルに移動します。そのため、PL/SQL パッケージ内から実行されることは認識されず、プライベート関数の呼び出しを許可する必要があります。
エンジンの違いは簡単に確認できると思います。32000 の varchar2 を使用してみてください。pl/sql 関数内で動作します。ここで、 を返す pl/sql 関数を呼び出すと、varchar2(32000)
失敗します。これは私が遭遇した問題ですが、スニペットを提供するデータベースがありません。
パッケージ本体でのみ宣言されている関数を使用できますが、最初に使用する前に宣言する必要があります。
create or replace package pkg_so is
function get2 return number;
end pkg_so;
/
create or replace package body pkg_so is
function get1 return number is
begin
return 1;
end;
function get2 return number is
begin
return get1 + 1;
end;
end pkg_so;
/
select pkg_so.get2 from dual
/
ええ、これは前方宣言と呼ばれます。プロシージャ/関数がパッケージsepcificarionで宣言されていない場合。次に、最初にbodyで使用される前に、最初にbodyで宣言する必要があります。
create or replace package pkg_so is
function get2 return number;
end pkg_so;
/
create or replace package body pkg_so is
function get1 return number is
begin
return 1;
end;
function get2 return number is
begin
return get1 + 1;
end;
end pkg_so;
/
select pkg_so.get2 from dual
/