You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PLSQL中%NOTFOUND简单测试案例未按预期工作问题

Oracle游标%NOTFOUND属性使用误区

问题核心在于:游标刚打开时,%NOTFOUND属性不会立即反映结果集是否为空。

当你执行OPEN c_dual2;后,Oracle仅初始化了游标对应的结果集,但并未从结果集中获取任何数据。此时c_dual2%NOTFOUND的值为NULL,而PL/SQL的IF判断会将NULL视为FALSE,因此会执行ELSE分支,输出"2 is found",这和实际结果集为空的情况不符。

要正确判断游标是否返回数据,必须先执行一次FETCH操作,让游标移动到结果集的第一行,之后%NOTFOUND属性才会正确反映是否存在数据。

修正后的代码示例

DECLARE
   CURSOR c_dual1 IS SELECT 1 FROM DUAL WHERE 1=1;
   CURSOR c_dual2 IS SELECT 1 FROM DUAL WHERE 1=2;
   v_num NUMBER; -- 用于存储FETCH的结果
BEGIN
   OPEN c_dual1;
   FETCH c_dual1 INTO v_num; -- 先获取第一行数据
   IF c_dual1%NOTFOUND THEN
      DBMS_OUTPUT.PUT_LINE ('1 is not found');
   ELSE
      DBMS_OUTPUT.PUT_LINE ('1 is found');
   END IF;
   CLOSE c_dual1;

   OPEN c_dual2;
   FETCH c_dual2 INTO v_num; -- 先获取第一行数据
   IF c_dual2%NOTFOUND THEN
      DBMS_OUTPUT.PUT_LINE ('2 is not found');
   ELSE
      DBMS_OUTPUT.PUT_LINE ('2 is found');
   END IF;
   CLOSE c_dual2;
END;

执行上述代码后,会得到你预期的输出:

1 is found
2 is not found

更简洁的替代写法

如果只是判断简单查询是否有结果,也可以直接用COUNT(*)查询,不需要显式游标:

DECLARE
   v_count NUMBER;
BEGIN
   SELECT COUNT(*) INTO v_count FROM DUAL WHERE 1=1;
   DBMS_OUTPUT.PUT_LINE (CASE WHEN v_count = 0 THEN '1 is not found' ELSE '1 is found' END);

   SELECT COUNT(*) INTO v_count FROM DUAL WHERE 1=2;
   DBMS_OUTPUT.PUT_LINE (CASE WHEN v_count = 0 THEN '2 is not found' ELSE '2 is found' END);
END;

内容的提问来源于stack exchange,提问作者Chad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 19:27:22