我有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 = ''';
答案 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,因此这似乎不会发生在这里。·
如果您没有在任何地方引用删除的列/字段,那么您无论如何都不应该选择它。将记录类型更改为仅包含您实际需要的字段,并仅在游标查询中获取相应的列。
如果您指的是已删除的列/字段,那么您仍然会被卡住 - 您已经找到了删除的内容以及原因,然后修复您的代码以便不引用它(如果是有意义的,或者让这种变化还原。