Oracle过程输入以逗号分隔,不返回任何值

时间:2013-01-25 16:26:03

标签: oracle plsql procedure delimited-text

我正在使用的程序有一个以逗号分隔的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陈述是正确的,所以我不知道我做错了什么。感谢任何帮助。谢谢。

1 个答案:

答案 0 :(得分: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