分页中的Oracle/PLSQL错误

问题描述:

嘿,我尝试添加paging在PLSQL但出于某种原因,我的动态SQL块,当我运行测试脚本就出现了错误:分页中的Oracle/PLSQL错误

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; 

我张贴以上犯规的错误是有意义的我,但我一直在寻找原因。如果任何人都可以指出我正确的方向,将非常感谢,提前感谢。

+0

您引用的错误是ORA-00932的规范形式;通常我会希望将'-'换成预期和得到的实际字符。不幸的是,你的信息已经丢失。 – 2013-02-12 02:54:59

我遇到了一些问题。

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

USING子句传递绑定变量

open p_return_cur_out 
    for lv_sql 
    using lv_startnum, lv_incrementby; 

有可能是,如果有更多的errors--,这将有助于张贴满堆栈跟踪包括错误的行号。

其他一些事情要注意。

  • 除非p_columnsort_in恰好指定列,它是独一无二的,您的分页代码很可能会错过行和/或显示行中的多个页面,因为排序顺序未完全指定。如果第20行和第21行具有相同的p_columnsort_in值,那么对第一个查询进行一种排序并对第二个查询进行另一种排序是完全合法的,因此第20行可能会显示在第一个和第二个页面上,而第21行可能不会显示在任何地方。
  • 如果考虑到效率问题,那么使用rownum最终可能比使用这样的分析函数更有效,因为优化程序通常可以更好地优化谓词谓词。
+0

谢谢,它看起来像是导致错误的提取。它从来没有跨过我的脑海,我需要补充说。 – 2013-02-08 20:36:47

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;