0

作業中のプロシージャには、inputカンマ区切りの変数があります。現在、テスト スクリプトを実行すると、値が返されません。これが私がこれまでに持っているものです。

procedure get_patient(
p_statusmnemonic_in    in membermedicalreconcilationhdr.reconciliationstatusmnemonic%type,
p_return_cur_out       out sys_refcursor,
p_err_code_out         out number,
p_err_mesg_out         out varchar2)
  is
  begin
open p_return_cur_out for
  select h.primarymemberplanid,
         h.assigneduserid,
         h.accountorgid,
         h.reconciliationstatusmnemonic,
         h.estimatedenddt,
         h.actualenddt,
         h.inserteddt,
         h.insertedby,
         h.updateddt,
         h.updatedby
  from membermedicalreconcilationhdr h
  where h.reconciliationstatusmnemonic in (p_statusmnemonic_in);
p_err_code_out := 0;
  exception
when others then
  p_err_code_out := -1;
  p_err_mesg_out := 'error in get_patient=> ' || sqlerrm;
  end get_patient;

テストスクリプトは次のとおりです。

set serveroutput on
declare
  type tempcursor is ref cursor;
  v_cur_result tempcursor;
  errcode number;
  errmesg varchar2(1000);
  p_primarymemberplanid_in    membermedicalreconcilationhdr.primarymemberplanid%type;
  p_assigneduserid_in         membermedicalreconcilationhdr.assigneduserid%type;
  p_accountorgid_in           membermedicalreconcilationhdr.accountorgid%type;
  p_reconstatusmnemonic_in        membermedicalreconcilationhdr.reconciliationstatusmnemonic%type;
  p_estimatedenddt_in         membermedicalreconcilationhdr.estimatedenddt%type;
  p_actualenddt_in            membermedicalreconcilationhdr.actualenddt%type;
  p_inserteddate_in           membermedicalreconcilationhdr.inserteddt%type;
  p_insertedby_in             membermedicalreconcilationhdr.insertedby%type;
  p_updateddate_in           membermedicalreconcilationhdr.updateddt%type;
  p_updatedby_in           membermedicalreconcilationhdr.updatedby%type;

begin
  get_patient      
('COMPLETE,SUSPENDED_PRIOR_TO_COMPARE',v_cur_result, errcode, errmesg);
--('COMPLETE',v_cur_result, errcode, errmesg);


   loop
fetch v_cur_result into p_primarymemberplanid_in,p_assigneduserid_in,p_accountorgid_in,p_reconstatusmnemonic_in,
                        p_estimatedenddt_in,p_actualenddt_in,p_inserteddate_in,p_insertedby_in,
                        p_updateddate_in,p_updatedby_in;

  dbms_output.put_line(' planid '||p_primarymemberplanid_in||' userid '||p_assigneduserid_in);
  exit when v_cur_result%notfound;
  end loop;

  dbms_output.put_line(' error code '||errcode||' message '||errmesg);
end;

現時点では、入力値が 1 つだけの場合は値が返されますが、2 つを実行しようとすると何も取得されません。私は調査を行いましたが、私のselect声明は正しいように見えるので、私が間違っていることについて途方に暮れています. どんな助けでも大歓迎です、ありがとう。

4

1 に答える 1

1

プロシージャの定義を変更できる場合は、適切なコレクションを渡す方が適切です。

CREATE TYPE status_tbl IS TABLE OF VARCHAR2(100);

procedure get_patient(
  p_statusmnemonic_in    in  status_tbl,
  p_return_cur_out       out sys_refcursor,
  p_err_code_out         out number,
  p_err_mesg_out         out varchar2)
is
begin
  open p_return_cur_out for
    select h.primarymemberplanid,
           h.assigneduserid,
           h.accountorgid,
           h.reconciliationstatusmnemonic,
           h.estimatedenddt,
           h.actualenddt,
           h.inserteddt,
           h.insertedby,
           h.updateddt,
           h.updatedby
      from membermedicalreconcilationhdr h
     where h.reconciliationstatusmnemonic in (SELECT * 
                                                FROM TABLE(p_statusmnemonic_in));
  ...

それ以外の場合は、動的SQL(セキュリティとパフォーマンスに影響があります)を使用するか、コンマ区切りの文字列をコレクションに解析するコードを記述してから、TABLE演算子を使用してクエリでそのコレクションを使用する必要があります。 。

プロシージャのシグニチャを変更すると仮定すると、コレクションを渡すように呼び出しも変更する必要があります。

get_patient      
(status_tbl('COMPLETE','SUSPENDED_PRIOR_TO_COMPARE'),
 v_cur_result, 
 errcode, 
 errmesg);

そして、それを指摘するために、OUT例外をスローするのではなく、エラーコードとエラーメッセージパラメータを持つプロシージャを作成することは、一般的に非常に眉をひそめています。これらのパラメータを削除し、エラーが発生したときに例外をスローする方がはるかに理にかなっています。それ以外の場合は、返されたステータスコードとメッセージを正しくチェックするために、すべてのプロシージャのすべての呼び出し元に依存しています(サンプルコードでは実行されません)。また、エラーが発生した行、エラースタックなどに関する貴重な情報が大量に失われています。

テーブル定義やサンプルデータを投稿しないため、このコードをテストすることはできません。ただし、これがどのように機能するかについての簡単なデモンストレーションです。

SQL> create table patient (
  2    patient_id number primary key,
  3    status     varchar2(10),
  4    name       varchar2(100)
  5  );

Table created.

SQL> insert into patient values( 1, 'COMPLETE', 'Justin' );

1 row created.

SQL> insert into patient values( 2, 'SUSPENDED', 'Bob' );

1 row created.

SQL> insert into patient values( 3, 'NEW', 'Kerry' );

1 row created.

SQL> commit;

Commit complete.

SQL> CREATE TYPE status_tbl IS TABLE OF VARCHAR2(100);
  2  /

Type created.

SQL> ed
Wrote file afiedt.buf

  1  create or replace procedure get_patients( p_statuses in status_tbl,
  2                                            p_cursor out sys_refcursor )
  3  as
  4  begin
  5    open p_cursor
  6     for select *
  7           from patient
  8          where status in (select *
  9                             from table( p_statuses ));
 10* end;
SQL> /

Procedure created.

SQL> variable rc refcursor;
SQL> exec get_patients( status_tbl('COMPLETE', 'SUSPENDED'), :rc );

PL/SQL procedure successfully completed.

SQL> print rc;

PATIENT_ID STATUS
---------- ----------
NAME
--------------------------------------------------------------------------------
         1 COMPLETE
Justin

         2 SUSPENDED
Bob
于 2013-01-25T16:54:48.190 に答える