0

以下のコードを使用して、「varchar のテーブル」と sys_refcursor を引数として取る DBMS_SQL でプロシージャを動的に実行しようとしています。

   DECLARE
   TYPE CriteriaMap IS TABLE OF VARCHAR (100)
                          INDEX BY VARCHAR2 (100);

   o_cursor             SYS_REFCURSOR;
   v_cid                INTEGER;
   v_dummy              INTEGER;
   v_date_to_run        DATE := SYSDATE;
   v_sql_execute_proc   VARCHAR2 (1024);
   v_filter_criteria    CriteriaMap;
BEGIN
   v_sql_execute_proc :=
      'begin MY_PROCEDURE(:v_date_to_run, :filter_criteria, :o_cursor); end;';
   v_cid := DBMS_SQL.open_cursor;
   DBMS_SQL.parse (v_cid, v_sql_execute_proc, DBMS_SQL.native);
   DBMS_SQL.bind_variable (v_cid, 'v_date_to_run', v_date_to_run);
   DBMS_SQL.bind_variable (v_cid, 'filter_criteria', v_filter_criteria);
   DBMS_SQL.bind_variable (v_cid, 'o_cursor', o_cursor);
   v_dummy := DBMS_SQL.execute (v_cid);
   DBMS_SQL.close_cursor (v_cid);
END;

その結果、次のエラーがスローされます

Error report:
ORA-06550: line 14, column 3:
PLS-00306: wrong number or types of arguments in call to 'BIND_VARIABLE'

ドキュメントhttp://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_sql.htmは、BIND_VARIABLEが限られた数のデータ型のみを取り、「varcharのテーブル」とsys_refcursorがリストにないことを示しています。

リストにないデータ型の動的関数に引数を渡す回避策はありますか?

4

2 に答える 2

0

私はそれが古いことを知っています...しかし、誰かがこれに遭遇した場合-sys refカーソルをカーソル番号に変換し、バインドし、実行後にrefcursorに変換することが可能です(11gでは、以前はわかりません)-何かのようなもの:

declare
   vSQL varchar2(1000) := 'declare 
                              v_rc sys_refcursor;
                           begin 
                              open v_rc for select ''this is a test'' from dual;
                              :v_cursor_number := dbms_sql.to_cursor_number(v_rc);
                           end;';
   v_rc sys_refcursor;
   v_cursor_number   NUMBER;
   v_cur number;
   v_result number;

   vFetchValue varchar2(20);
begin
   --open the cursor
   v_cur := DBMS_SQL.OPEN_CURSOR;
   --parse
   DBMS_SQL.PARSE(v_cur, vSQL, dbms_sql.native);
   --bind the cursor number
   DBMS_SQL.BIND_VARIABLE(v_cur, 'v_cursor_number', v_cursor_number);
   --execute
   v_result := DBMS_SQL.EXECUTE(v_cur);
   -- get back the value of the bind cursor number
   DBMS_SQL.VARIABLE_VALUE(v_cur,'v_cursor_number', v_cursor_number);
   --transform it to a standard sys_refcursor
   v_rc := DBMS_SQL.TO_REFCURSOR (v_cursor_number);
   --close the cursor
   DBMS_SQL.CLOSE_CURSOR(v_cur);

   fetch v_rc into vFetchValue;
   close v_rc;
   dbms_output.put_line(vFetchValue);

end;
/
于 2014-05-08T09:44:45.533 に答える
0

varchar のテーブルは、bind_array を介してサポートされます (ただし、varchar2 ではなく整数でインデックス付けされる dbms_sql の仕様に従っている必要があります)。

この場合、動的 SQL を使用している理由について詳しく説明できますか? 呼び出しの構造がここで固定されているため、あなたの例は動的SQLを保証しません。

于 2012-11-14T08:11:24.667 に答える