2017-12-27 201 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,所以看起来并不是什么发生在这里。)

如果你不是指任何地方的删除列/字段,那么你不应该选择它。将记录类型更改为仅包含实际需要的字段,并且只获取游标查询中的相应列。

如果你指的是删除的列/字段,那么你仍然被卡住 - 你会发现什么被删除,为什么,然后修复你的代码不参考它(如果这是有道理的) ,或者让这个改变恢复。

相关问题