私の理解はOUTです。仮パラメータは、プロシージャが呼び出されると常にNULLにデフォルト設定する必要があります。OracleのoutパラメータがNULLでない場合
create or replace package parameter_tests as
procedure callerproc;
end parameter_tests;
/
create or replace package body parameter_tests as
procedure getstring(p_str out varchar) is
begin
if p_str is null then
dbms_output.put_line('parameter null');
else
dbms_output.put_line('parameter NOT null');
end if;
p_str :='zz';
end getstring;
procedure getcursor(p_out out sys_refcursor) is
begin
if p_out%isopen then
dbms_output.put_line('cursor open');
else
dbms_output.put_line('cursor closed');
end if;
open p_out for
select *
from dual;
end getcursor;
procedure callerproc is
lv_cursor sys_refcursor;
lv_string varchar2(2) := null;
begin
for i in 1..2 loop
getstring(lv_string);
getcursor(lv_cursor);
end loop;
end callerproc;
end parameter_tests;
/
set serveroutput on
begin
parameter_tests.CALLERPROC;
end;
/
parameter_tests.getstringは、callerprocループの周りに「パラメータnull」を両方とも出力すると予想します。そして、コードを実行すると、まさにそれが起こります。
しかし、parameter_tests.getcursorの出力は、参照カーソルがループの周りで2度目に開いていることを示します。
getcursorが呼び出されたときに仮パラメータp_outがNULLになっていれば、参照カーソルを閉じることができます。その代わりに、開いている参照カーソルを渡します。実際には、開いている参照カーソルを整理するOPEN FOR(何百回も繰り返すと最大オープンカーソルに当たらないようにします)です。
私は手動で呼び出し間の参照カーソルをnullにすると、期待どおりの動作をします。
OUTパラメータの場合、参照カーソルが特別なケースとして扱われる理由は誰にでも分かりますか?また、他のどのような種類の処理が異なっていますか?
データベースのバージョンは11.2.0.2.0です。
偉大な答え。ありがとうございました。あなたは明白な閉鎖が最良の選択であることについて正しいです。問題の原因は、実際にはクローズされていないカーソルの問題を調査しており、カーソルをループで開くことでカーソルの制限を超えることができないことがわかった。 –