2017-12-27 202 views
0

我有甲骨文的PL/SQL程序:ORA-01007:變量未在選擇列表中同時獲取C2到標記2下面

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; 

當我做下面的操作

FETCH C2 INTO Cursor2; 

我得到這個錯誤:

ORA-01007:變量不在選擇列表錯誤。

這段腳本曾經工作過。

如何解決此問題?

腳本

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

的簡化版本,你看到什麼,有虛表,簡單的匿名塊:

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. 

爲了讓你看到我只需要到錯誤刪除表的一列:

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塊中聲明的記錄類型中的字段列表不再匹配遊標查詢中的列類型。您正在讀取的記錄變量需要兩列(在我的版本中,22位在您的),但查詢只獲取一個值。

可以(有些人會說應該)指定所有你明確選擇列,但假設你實際上指的是所有這些以後,你會那麼做了相當於:

open l_cur for 'select id, some_value from t42'; 

它仍然會在塔移出後出錯,雖然有點更有益也許是:

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

由於您目前打算從單一的表中獲取所有列,你也可以使用了the %rowtype語法而不是您自己的記錄類型:

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,所以看起來並不是什麼發生在這裏。)

如果你不是指任何地方的刪除列/字段,那麼你不應該選擇它。將記錄類型更改爲僅包含實際需要的字段,並且只獲取遊標查詢中的相應列。

如果你指的是刪除的列/字段,那麼你仍然被卡住 - 你會發現什麼被刪除,爲什麼,然後修復你的代碼不參考它(如果這是有道理的) ,或者讓這個改變恢復。

相關問題