Oracle 无法在INTO list中混合使用单行和多行(批量)。proc中出现错误
已编译过程ATCHMNT\u ERR\u FILEID 错误:检查过程的编译器日志错误 RDBSTAGE.ATCHMNT\u ERR\u文件ID: 行/列错误 11/40 PLS-00497:不能在列表中混合单行和多行批量 14/5 PL/SQL:忽略语句 14/31 PLS-00302:必须声明组件“计数” PLS-00497:无法在列表中混合单行和多行批量 BULK COLLECT INTO是用于从查询填充PL/SQL集合的语法。但您的代码正在填充标量单行变量 14/31 PLS-00302:必须声明组件“计数” I_ATCHMNT_ERR.COUNT无效,因为COUNT仅适用于集合I_ATCHMNT_ERR为标量 要解决此问题,您需要定义和使用集合类型。大概是这样的:Oracle 无法在INTO list中混合使用单行和多行(批量)。proc中出现错误,oracle,stored-procedures,plsql,Oracle,Stored Procedures,Plsql,已编译过程ATCHMNT\u ERR\u FILEID 错误:检查过程的编译器日志错误 RDBSTAGE.ATCHMNT\u ERR\u文件ID: 行/列错误 11/40 PLS-00497:不能在列表中混合单行和多行批量 14/5 PL/SQL:忽略语句 14/31 PLS-00302:必须声明组件“计数” PLS-00497:无法在列表中混合单行和多行批量 BULK COLLECT INTO是用于从查询填充PL/SQL集合的语法。但您的代码正在填充标量单行变量 14/31 PLS-00302
CREATE OR REPLACE PROCEDURE RDBSTAGE.ATCHMNT_ERR_FILEID AUTHID CURRENT_USER
IS
CURSOR cv_atchtab IS
SELECT * FROM ATTACHMENT_ERROR;
I_ATCHMNT_ERR cv_atchtab%ROWTYPE;
V_FILE_ID VARCHAR2(40);
BEGIN
OPEN cv_atchtab;
LOOP
FETCH cv_atchtab BULK COLLECT INTO I_ATCHMNT_ERR;
EXIT WHEN cv_atchtab%NOTFOUND;
FOR i IN 1..I_ATCHMNT_ERR.COUNT
LOOP
SELECT FILE_ID BULK COLLECT
INTO V_FILE_ID
FROM ATTACHMENT_CLAIM t1
WHERE t1.CLAIM_TCN_ID=I_ATCHMNT_ERR(i).CLAIM_TCN_ID;
UPDATE ATTACHMENT_ERROR
SET FILE_ID = V_FILE_ID
WHERE t1.CLAIM_TCN_ID=I_ATCHMNT_ERR.CLAIM_TCN_ID;
END LOOP;
END LOOP;
CLOSE cv_atchtab;
END;
END ATCHMNT_ERR_FILEID;
/
SHOW ERRORS
这是与我对数据模型的猜测相反的
Oracle文档内容全面、在线且免费。PL/SQL指南有一整章关于集合和记录,我建议您阅读
另一方面,在PL/SQL中,具有类似这样的单行语句的嵌套循环通常是一个危险信号。它们效率很低,速度也很慢。SQL是一种基于集合的语言,我们应该尽可能使用SQL解决问题,最好是使用一个基于集合的语句。如果这段代码是为了生产而不是作为作业,你应该考虑重新写一个更具表现力的方式。为了将来的参考,请编辑你的问题,包括附加信息或澄清。这是一个学习练习吗?或者这是生产代码?@boneist-我希望这不是生产代码。我已经运行了新的更改,但得到了以下内容A-00904:t1。声明\u TCN\u ID无效标识当前获取此行/COL错误--------------------------------------------25/21 PLS-00642:SQL语句中不允许使用本地集合类型我使用了Oracle数据库12cSo在我以前的代码版本中,我也将V_FILE_ID作为一个集合。但是没有更改UPDATE语句中的SET子句。这就是PLS-00642错误的原因。我通过将V_FILE_ID恢复为标量并在填充大容量COLLECT子句时将其删除,解决了这个问题。我没有发现这个错误,因为我最初的测试与您的场景不完全相同。所以我也做了您应该做的事情,并提供了一个完整的工作测试用例。找到我的。
CREATE OR REPLACE PROCEDURE ATCHMNT_ERR_FILEID
IS
CURSOR cv_atchtab IS
SELECT * FROM ATTACHMENT_ERROR;
type ATCHMNT_ERR_nt is table of cv_atchtab%ROWTYPE;
I_ATCHMNT_ERR ATCHMNT_ERR_nt;
V_FILE_ID VARCHAR2(40);
BEGIN
OPEN cv_atchtab;
LOOP
FETCH cv_atchtab BULK COLLECT INTO I_ATCHMNT_ERR; -- collection type
EXIT WHEN I_ATCHMNT_ERR.COUNT = 0; -- changed this
FOR i IN 1..I_ATCHMNT_ERR.COUNT
LOOP
SELECT FILE_ID
INTO V_FILE_ID -- scalar type
FROM ATTACHMENT_CLAIM t1
WHERE t1.CLAIM_TCN_ID = I_ATCHMNT_ERR(i).CLAIM_TCN_ID;
UPDATE ATTACHMENT_ERROR t2 -- changed this
SET FILE_ID = V_FILE_ID
WHERE t2.CLAIM_TCN_ID = I_ATCHMNT_ERR(i).CLAIM_TCN_ID; -- changed this
END LOOP;
END LOOP;
CLOSE cv_atchtab;
END ATCHMNT_ERR_FILEID;