2017-12-27 635 views
0

にC2をフェッチしながら、私は以下を使用してOracle PL/SQLプロシージャを持っている:私は、以下の操作ORA-01007:選択リスト内の変数ではないCursor2の

FETCH C2 INTO Cursor2; 

を行う際

TYPE Paycomp2 IS RECORD(
     Row_Id   VARCHAR2(15), 
     Created   DATE, 
     Created_By  VARCHAR2(15), 
     Last_Upd   DATE, 
     Last_Upd_By  VARCHAR2(15), 
     Modification_Num NUMBER(10), 
     Conflict_Id  VARCHAR2(15), 
     Comp_Price  NUMBER(10), 
     Access_Level  VARCHAR2(30), 
     Comp_Name  VARCHAR2(30), 
     Depends_On  VARCHAR2(30), 
     Gold_Cat   VARCHAR2(30), 
     Order_Type  VARCHAR2(30), 
     Parent_Id  VARCHAR2(15), 
     Price_Plan  VARCHAR2(30), 
     TYPE    VARCHAR2(30), 
     Check_Flag  VARCHAR2(1), 
    PREPAID_INIT_PRICE number(10), 
    DB_LAST_UPD  date, 
    DB_LAST_UPD_SRC varchar2(50), 
    Unit_Type  varchar2(30), 
    M2M_CATEGORY  varchar2(30)); 
    TYPE Paycomp IS REF CURSOR; 
    C2    Paycomp; 
    Cursor2  Paycomp2; 

私は取得していますこのエラー:

ORA-01007:変数が選択リスト・エラーにありません。

このスクリプトは以前に動作しました。

この問題を解決するにはどうすればよいですか?あなたは、私はちょうどする必要が見ているエラーを取得するために

create table t42 (id number, some_value varchar2(10)); 

declare 
    type t_rec is record(id number, some_value varchar2(10)); 
    l_rec t_rec; 
    l_cur sys_refcursor; 
begin 
    open l_cur for 'select * from t42'; 
    fetch l_cur into l_rec; 
    close l_cur; 
end; 
/

PL/SQL procedure successfully completed. 

スクリプト

Vordertype := 'Migration Prepaid - Postpaid'; 

Curcomp_Sql := Curcomp_Sql || Vordertype || '''' || ' union all ' || '' || Curcomp2sql || '' || 
          Vordertype || ''''; 

OPEN C2 FOR Curcomp_Sql; 

Sadmin.Pkg_Spliter.Prcsplitchar(Ppaycompstr, ';', Arrcomplist); 

Vtotalcompprc := 0; 
Arrcount  := Arrcomplist.Count; 

BEGIN 

Dbms_output.put_line('reached17'); 
    LOOP 

     FETCH C2 
      INTO Cursor2; 
      Dbms_output.put_line('reached18'); 
     EXIT WHEN C2%NOTFOUND; 
     -- Processing each entry from Array 
     Compfndflg := 0; 
     dbms_output.put_line('arrCount 0: reached'); 
     FOR Counter IN 1 .. Arrcount 
     LOOP 
      Vstrcommand := Arrcomplist(Counter); 
      dbms_output.put_line('arrCount : reached'); 
      Sadmin.Pkg_Spliter.Prcsplitchar(Vstrcommand, '?', Arrdisclist); 
      IF Arrdisclist.Count <> 0 THEN 
       dbms_output.put_line('arrCount : reached1'); 
       -- Extracting the ? seperated values and putting them into variables 
       Vcompname := Arrdisclist(1); 
       --dbms_output.put_line(CURSOR2.comp_name||':- count -'||COUNTER||'--'||VCOMPNAME); 
       BEGIN 
        -- Added by Accenture 
        IF Vcompname IS NOT NULL THEN 
         --dbms_output.put_line(CURSOR2.comp_name||':- count -'||COUNTER||'--'||ARRDISCLIST(1)||'-'||ARRDISCLIST(2)||'-'||ARRDISCLIST(3)); 
         SELECT COUNT(0) 
         INTO v_Count_Exist 
         FROM Siebel.Cx_Paycomp_Mtx a, Siebel.Cx_Paycomp_Mtx b 
         WHERE a.Row_Id = b.Parent_Id 
         AND a.Order_Type = Vordertype 
         AND b.Type = 'Payment Component' 
         AND b.Comp_Name = Vcompname; 
         IF (v_Count_Exist = 0) THEN 
          Err_Msg := 'Invalid Payment Component in String'; 
          Result_Out := '74'; 
          Errflg  := 1; 
          --dbms_output.put_line('Counter 2' || counter); 
          --dbms_transaction.rollback; 
          RAISE Error_Out; 
         END IF; 
        END IF; 
        --dbms_output.put_line('Counter 3' || CURSOR2.comp_name); 
        IF Vcompname = Cursor2.Comp_Name 
        --and VCOMPNAME != '3' 
        THEN 
         Compfndflg := 1; 
         EXIT; 
        END IF; 
       END; 
      END IF; 
     END LOOP; 
       ---DBMS_OUTPUT.PUT_LINE('VCOMPNAME, COMPFNDFLG'||VCOMPNAME||','||COMPFNDFLG); 
     --dbms_output.put_line('CURSOR2.comp_name :'||CURSOR2.comp_name||' - COMPFNDFLG :'||COMPFNDFLG); 
     IF Compfndflg != 1 THEN 

      IF Temp_Comp_String IS NULL THEN 
       Temp_Comp_String := Cursor2.Comp_Name || '?0?;'; 
       ---DBMS_OUTPUT.PUT_LINE('STRING 1'||TEMP_COMP_STRING); 
      ELSE 
       Temp_Comp_String := Temp_Comp_String || Cursor2.Comp_Name || '?0?;'; 
       ---DBMS_OUTPUT.PUT_LINE('STRING 2'||TEMP_COMP_STRING); 
      END IF; 
      --- END IF; 
     ELSE 

      IF Temp_Comp_String IS NULL THEN 
       Temp_Comp_String := Arrdisclist(1) || '?' || Arrdisclist(2) || '?' || 
                 Arrdisclist(3) || ';'; 
       ---DBMS_OUTPUT.PUT_LINE('STRING 3'||TEMP_COMP_STRING); 
      ELSE 
       Temp_Comp_String := Temp_Comp_String || Arrdisclist(1) || '?' || Arrdisclist(2) || '?' || 
                 Arrdisclist(3) || ';'; 
       ---DBMS_OUTPUT.PUT_LINE('STRING 4'||TEMP_COMP_STRING); 
      END IF; 
      --   end if; 
      --- END IF; 
     END IF; 
    END LOOP; 
END; 



Curcomp_Sql VARCHAR2(2000) := 'SELECT mtx2.* 
      FROM siebel.CX_PAYCOMP_MTX mtx1, siebel.CX_PAYCOMP_MTX mtx2 
     WHERE mtx2.parent_id = mtx1.row_id 
      AND mtx2.comp_name <> ''Security Deposit'' 
      AND mtx2.TYPE = ''Payment Component'' 
      AND mtx1.order_type = '''; 


Curcomp2sql VARCHAR2(2000) := 'SELECT mtx2.* 
      FROM siebel.CX_PAYCOMP_MTX mtx1, siebel.CX_PAYCOMP_MTX mtx2 
     WHERE mtx2.parent_id = mtx1.row_id 
      AND mtx2.comp_name = ''Security Deposit'' 
      AND mtx2.TYPE = ''Payment Component'' 
      AND mtx2.depends_on = ''ACCESS LEVEL'' 
      AND mtx1.order_type = '''; 
+0

SELECT文を表示してください –

+2

'SELECT mtx2。*'は使用しないでください。 'mtx2'から選択している列のリスト全体を指定します。 'SELECT mtx2.Row_Id、mtx2.Created、mtx2.Created_By、...'など –

+0

'CX_PAYCOMP_MTX'テーブルの構造がおそらく変更されているので、' * 'を選択するとそのレコードタイプに一致しなくなります。なぜあなたは '%rowtype'を使うのではなく、あなた自身のレコードタイプを定義していますか? (あなたが必要とする列を記入することはおそらくもっと良いですが)。なぜバインド変数を使用するのではなく、クエリに値を連結するのですか?感謝! –

答えて

1

あなたはダミーのテーブルとシンプルな無名ブロックで、見ているものの簡易版表の列の1削除:

alter table t42 drop column some_value; 

をし、再び、全く同じコードを実行します。

declare 
    type t_rec is record(id number, some_value varchar2(10)); 
    l_rec t_rec; 
    l_cur sys_refcursor; 
begin 
    open l_cur for 'select * from t42'; 
    fetch l_cur into l_rec; 
    close l_cur; 
end; 
/

ORA-01007: variable not in select list 
ORA-06512: at line 10 

PL/SQLブロックで宣言されたレコード・タイプのフィールド・リストは、カーソル照会の列タイプと一致しなくなりました。フェッチしているレコード変数は、2つのカラム(私のバージョンでは22個)を必要としますが、クエリは1つの値しか取得しません。

あなたが(一部は べきだと思います)あなたが明示的に選択しているすべての列を指定することができますが、実際にそれらを参照していると仮定すると、すべての後にあなたが、その後の同等行っているでしょう

open l_cur for 'select id, some_value from t42'; 
をまだ列除去した後にエラーが発生したただろう

、より親切おそらくビットはかかわら:

ORA-00904: "SOME_VALUE": invalid identifier 
ORA-06512: at line 9 

あなたは現在、単一のテーブルからすべての列を取得しようとしているので、あなたも使用している可能性がこの独自のレコードタイプではなく、という構文を使用します。

declare 
    l_rec t42%rowtype; 
    l_cur sys_refcursor; 
begin 
    open l_cur for 'select * from t42'; 
    fetch l_cur into l_rec; 
    close l_cur; 
end; 
/

この簡単な例では正常に実行されます。あなたはまだそれがまだレコードの一部だと仮定すると、しかし、すぐに削除した列を参照するなどの問題があるでしょう:

declare 
    l_rec t42%rowtype; 
    l_cur sys_refcursor; 
begin 
    open l_cur for 'select * from t42'; 
    fetch l_cur into l_rec; 
    dbms_output.put_line(l_rec.some_value); 
    close l_cur; 
end; 
/

ORA-06550: line 7, column 30: 
PLS-00302: component 'SOME_VALUE' must be declared 
ORA-06550: line 7, column 3: 
PL/SQL: Statement ignored 

(カラムはを追加された場合、あなたにいくつかの呼吸スペースを与えるだろう%rowtypeを使用して、そのレコードフィールドを参照するコードを追加しない限り、無視されますが、コードではORA-00932のデータ型がORA-01007ではなくORA-00932になります。 )

削除された列/フィールドを参照していない場合は、とにかく選択しないでください。実際に必要なフィールドのみを含めるようにレコードタイプを変更し、カーソルクエリの対応する列のみを取得します。

削除された列/フィールドを参照している場合は、とにかく詰まっています。削除されたものとその理由を見つけて、それを参照しないようにコードを修正します、またはその変更を元に戻す。

関連する問題