PL/SQL 异常 ORA-06511 游标已打开

Posted

技术标签:

【中文标题】PL/SQL 异常 ORA-06511 游标已打开【英文标题】:PL/SQL exception ORA-06511 cursor already open 【发布时间】:2018-06-02 09:10:11 【问题描述】:

最近我们在我们的应用程序日志中看到以下错误,这种情况只是偶尔发生(一周左右一次),这使我们相信游标异常仅由某些特定的输入条件/未处理的异常引发。

错误 - SQL 状态 [24000];错误代码 [6511]; ORA-06511: PL/SQL: 游标已打开 ORA-06512:在“PACKAGE”,第 3 行 ORA-06512:在“APPS.TLN_AR_ONLINE_LIST2_PKG”,第 17 行

嵌套异常是 java.sql.SQLException: ORA-06511: PL/SQL: cursor already open ORA-06512: 在“PACKAGE”,第 3 行 ORA-06512: 在 " PACKAGE \, line 17, "providerErrorMessage":"CallableStatementCallback; SQL 的未分类 SQLException

所以我们打开包并检查光标和错误所在的行号。

1.     CURSOR c_t_num (trx_num_tran.trx_number%TYPE)
2.     IS
3.        SELECT interface_header_attribute1**
4.          FROM ra_customer_trx_all
5.         WHERE trx_number = trx_num;
6.           OPEN c_t_num (trx_list_rec.trx_number);
7.  
8.           FETCH c_t_num
9.            INTO t_rf_trx_number;
10. 
11.          IF c_t_num%NOTFOUND
12.          THEN
13.             t_rf_trx_number := NULL;
14.          END IF;
15. 
16.          CLOSE c_t_num;
17. OPEN c_t_num (p_trx_num);
18. 
19.       FETCH c_t_num
20.        INTO t_trx_number;
21. 
22.       IF c_t_num%NOTFOUND
23.       THEN
24.          t_trx_number := NULL;
25.       END IF;
26. 
27.       CLOSE c_t_num;
28. 

29. OPEN c_t_num (v_trx_num);
30. 
31.       FETCH c_t_num
32.        INTO t_trx_num_ritel;
33. 
34.       CLOSE c_t_num;
35. 
36.       RETURN (t_trx_num_ritel);
37.    END get_trx_number;

现在,光标在第 6,17 和 29 行打开。但异常总是显示第 3 行(光标定义的选择)和第 17 行。

这是一个隐式类型游标(这是一个遗留代码)吗?我们认为异常处理可能是问题所在?

在所有块中,包括当我们从第 17 行打开游标时,我们对未找到数据但对于 TOO_MANY_ROWS 没有异常处理。

任何人都可以就这个问题提供帮助/建议吗?

【问题讨论】:

代码看起来无效。像这样的游标需要在declare 部分中声明,即在function get_trx_number ... isbegin 之间。您不能只从cursor c_t_num is... 转到open c_t_num。此外,我没有看到任何异常处理,或no_data_foundtoo_many_rows 可能发生的任何地方。 虽然您发布的代码看起来并不完整,但我们甚至很难在“仅偶尔发生(一周左右一次)”的情况下进行调试。这是您的数据库和环境设置,您最清楚发生这种情况的原因。一种方法是将代码中的更多信息添加到日志中,并尝试在测试设置中重新创建那个神秘的场景。我怀疑是否有人可以在这方面为您提供更多帮助,除非您提供更多关于可能是什么问题的线索。 嗨 - 我只粘贴了一个 sn-p,我无法粘贴整个代码,声明部分确实包含 no_data_found 异常处理,但我看不到 too_many_rows 的任何异常处理。我与 BA 交谈过,显然预期的行为是仅获取/检索 1 行。我们怀疑某些功能更改正在破坏这一点,并且光标和匹配行之间的 1-1 映射被破坏 【参考方案1】:

在打开光标之前(在本例中名为 c_main_script_1),请执行以下操作:

if c_main_script_1%isopen then
    close c_main_script_1;
end if;

-莉亚·贾维斯

【讨论】:

以上是关于PL/SQL 异常 ORA-06511 游标已打开的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 没有发现游标的数据异常

zbb20170601 oracle PL/SQL 语句块 游标 自定义游标 异常处理EXCEPTION

PL/SQL轻量版——游标与异常处理

Oracle笔记4-pl/sql-分支/循环/游标/异常/存储/调用/触发器

pl/sql打开游标问题

Oralce-PL/SQL编程-游标