1

嘿,我正在尝试paging在 PLSQL 中添加我的动态 sql 块,但是由于某种原因,当我运行测试脚本时它会出错:

ORA-00932: inconsistent datatypes: expected - got -

这是我的程序:

create or replace 
  procedure spm_search_patientmedrecs (
    p_columnsort_in       in varchar2,
    p_column1_in          in varchar2,
    p_column2_in          in varchar2,
    p_column3_in          in varchar2,
    p_column4_in          in varchar2,
    p_ascdesc_in          in varchar2,
    p_return_cur_out      out sys_refcursor
  is
    lv_sql             varchar2(32767);
    lv_startnum        number:= 1;
    lv_incrementby     number:= 20;
  begin
    lv_sql := '';    
        lv_sql := 'select * from (
                   select /*+ first_rows(20) */
                      '||p_column1_in||',
                      '||p_column2_in||',
                      '||p_column3_in||',
                      '||p_column4_in||',
                      row_number() over
                        (order by '||p_columnsort_in||' '||p_ascdesc_in||') rn
                   from membermedicalreconcilationhdr h,
                        membermedicalreconcilationdet d
                   where h.membermedreconciliationhdrskey = 
                         d.membermedreconciliationhdrskey)
                   where rn between :lv_startnum and :lv_incrementby
                   order by rn';

        open p_return_cur_out for lv_sql;
  end spm_search_patientmedrecs;

这是我的测试脚本:

  set serveroutput on
  declare 
    type tempcursor is ref cursor;
    v_cur_result tempcursor;
    p_columnsort_in   varchar2(50);
    p_column1_in      varchar2(50);
    p_column2_in      varchar2(50);
    p_column3_in      varchar2(50);
    p_column4_in      varchar2(50);
    p_ascdesc_in          varchar2(50);
  begin
    spm_search_patientmedrecs
    ('h.PRIMARYMEMBERPLANID',
     'h.PRIMARYMEMBERPLANID',
     'h.ASSIGNEDUSERID',
     'd.MEMBERMEDRECONCILIATIONDETSKEY',
     'd.GENERICNM',
     'ASC',
     v_cur_result
     );
   loop
      fetch v_cur_result into
        p_column1_in,p_column2_in,p_column3_in,p_column4_in;
        dbms_output.put_line('column 1: '||p_column1_in||' column 2: '||p_column2_in||
                             ' column 3: '||p_column3_in||' column 4: '||p_column4_in);
      exit when v_cur_result%notfound;
    end loop;
  end;

我上面发布的错误对我来说没有意义,但我一直在寻找原因。如果有人能指出我正确的方向,将不胜感激,在此先感谢。

4

2 回答 2

1

我突然想到了几个问题。

  • 您用于返回游标的查询返回 5 列(传入的 4 列加上计算的rn),而您fetch仅将数据提取到 4 个变量中。您要么需要修改查询以仅返回 4 列,要么修改测试脚本以将数据提取到 5 个变量中。
  • 在您的过程中,您的 SQL 语句中有绑定变量,但您在打开游标时没有传入任何绑定变量。我的猜测是你想要这样的东西

USING使用子句传递绑定变量

open p_return_cur_out 
     for lv_sql 
   using lv_startnum, lv_incrementby;

可能还有更多错误——如果有,发布完整的堆栈跟踪(包括错误的行号)会很有帮助。

还有几件事需要注意。

  • 除非p_columnsort_in碰巧指定了唯一的列,否则您的分页代码很可能会错过行和/或在多个页面中显示行,因为没有完全指定排序顺序。如果第 20 行和第 21 行具有相同的p_columnsort_in值,则在第一个查询中以一种方式对它们进行排序而在第二个查询中以另一种方式对它们进行排序是完全合法的,因此第 20 行可能会出现在第一页和第二页上,而第 21 行可能不会出现任何地方。
  • 如果效率是一个问题,那么使用rownum可能最终会比使用这样的分析函数更有效,因为优化器通常可以更好地优化rownum谓词。
于 2013-02-08T20:30:16.497 回答
1
create or replace 
  procedure spm_search_patientmedrecs (
    p_columnsort_in       in varchar2,
    p_column1_in          in varchar2,
    p_column2_in          in varchar2,
    p_column3_in          in varchar2,
    p_column4_in          in varchar2,
    p_ascdesc_in          in varchar2,
    p_return_cur_out      out sys_refcursor
  is
    lv_sql             varchar2(32767);
    lv_startnum        number:= 1;
    lv_incrementby     number:= 20;
  begin
        lv_sql := 'select * from (
                   select /*+ first_rows(20) */
                      '||p_column1_in||',
                      '||p_column2_in||',
                      '||p_column3_in||',
                      '||p_column4_in||',
                      row_number() over
                        (order by '||p_columnsort_in||' '||p_ascdesc_in||') rn
                   from membermedicalreconcilationhdr h,
                        membermedicalreconcilationdet d
                   where h.membermedreconciliationhdrskey = 
                         d.membermedreconciliationhdrskey)
                   where rn between :1 and :2
                   order by rn';
        open p_return_cur_out for lv_sql using lv_startnum, lv_incrementby;
  end spm_search_patientmedrecs;
于 2013-02-08T20:30:29.833 回答