lea*_*sql 3 oracle plsql temp-tables
我在里面有以下内容package,它给了我一个错误:
ORA-14551: cannot perform a DML operation inside a query
Run Code Online (Sandbox Code Playgroud)
代码是:
DECLARE
CURSOR F IS
SELECT ROLE_ID
FROM ROLE
WHERE GROUP = 3
ORDER BY GROUP ASC;
BEGIN
FOR R IN F LOOP
DELETE FROM my_gtt_1;
COMMIT;
INSERT INTO my_gtt_1
( USER, role, code, status )
(SELECT
trim(r.user), r.role, r.code, MAX(status_id)
FROM
table1 r,
tabl2 c
WHERE
r.role = R.role
AND r.code IS NOT NULL
AND c.group = 3
GROUP BY
r.user, r.role, r.code);
SELECT c.role,
c.subgroup,
c.subgroup_desc,
v_meb_cnt
INTO record_type
FROM ROLE c
WHERE c.group = '3' and R.role = '19'
GROUP BY c.role,c.subgroup,c.subgroup_desc;
PIPE ROW (record_type);
END LOOP;
END;
Run Code Online (Sandbox Code Playgroud)
我在我的一个程序中调用这样的包...:
OPEN cv_1 for SELECT * FROM TABLE(my_package.my_func);
Run Code Online (Sandbox Code Playgroud)
我怎么能避免这个ORA-14551错误?
仅供参考我没有在循环中粘贴整个代码.基本上在循环内部我在GTT中输入内容,从GTT中删除内容然后从GTT中选择内容并将其附加到光标.
APC*_*APC 10
错误的含义非常明确:如果我们从SELECT语句调用一个函数,它就不能执行DML语句,即INSERT,UPDATE或DELETE,或者实际上是DDL语句.
现在,您发布的代码片段包含对PIPE ROW的调用,所以显然您将其称为SELECT*FROM TABLE().但它包含DELETE和INSERT语句,因此很明显它违反了SELECT语句中函数所需的纯度级别.
因此,您需要删除这些DML语句.您正在使用它们来填充全局临时表,但这是个好消息.您没有包含任何实际使用GTT的代码,因此很难确定,但使用GTT通常是不必要的.有了更多细节,我们可以建议解决方法.
这与你的其他问题有关吗?如果是这样,你是否按照我的建议检查我给出的类似问题的答案?
为了完整起见,可以在SELECT语句中调用的函数中包含DML和DDL语句.解决方法是使用AUTONOMOUS_TRANSACTION编译指示.这很少是一个好主意,在这种情况下肯定无济于事.因为事务是自治的,所以它所做的更改对于调用事务是不可见的.在这种情况下意味着该功能无法在GTT中看到删除或插入的结果.
| 归档时间: |
|
| 查看次数: |
28787 次 |
| 最近记录: |