1

pagingPLSQL で動的 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列と計算された列)を返しますがrnfetchデータを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値が同じである場合、最初のクエリで1つの方法で並べ替え、2番目のクエリで別の方法で並べ替えて、行20が1ページ目と2ページ目に表示され、行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 に答える