ORA-01007:将c2提取到cursor2时,变量不在选择列表中

时间:2017-12-27 13:18:23

标签: oracle plsql

我有oracle pl / sql程序,如下所示:

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 = ''';

1 个答案:

答案 0 :(得分: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,因此这似乎不会发生在这里。·

如果您没有在任何地方引用删除的列/字段,那么您无论如何都不应该选择它。将记录类型更改为仅包含您实际需要的字段,并仅在游标查询中获取相应的列。

如果您指的是已删除的列/字段,那么您仍然会被卡住 - 您已经找到了删除的内容以及原因,然后修复您的代码以便不引用它(如果是有意义的,或者让这种变化还原。