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;

截至目前,当我只有一个输入值时,我会返回值,但是当我尝试做两个时,我什么也得不到。我做了研究,看起来我的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 回答