【问题标题】:pl sql %NOTFOUNDpl sql %NOTFOUND
【发布时间】:2012-10-25 19:09:50
【问题描述】:

我只是想知道为什么这段代码不起作用。我的表中没有任何供应商id=1。

DECLARE
    VAR SUPP_NM VARCHAR(100);
    VAR_SUPP_ID  NUMBER := 1;
    WHILE_VAR CHAR := 'Y';
BEGIN
    SELECT SUPP_NM
    INTO VAR_SUPP_NM
    FROM TEST.SUPPLIER
    WHERE SUPP_ID = VAR_SUPP_ID;
        
    IF SQL%NOTFOUND THEN
        DBMS_OUTPUT.PUT_LINE('SQL DATA NOT FOUND');
    ELSIF SQL%FOUND THEN
        DBMS_OUTPUT.PUT_LINE('DATA FOUND');
    END IF;    
END;

我在 Toad 中收到 01403 错误,但未作为 sql%notfound 处理。

为什么sql%notfound 不起作用?

【问题讨论】:

  • 请将该信息编辑到您的问题中。 (并且总是在发布问题时直接在问题中准确说出正在发生的事情/将来会遇到什么错误。这非常重要。)

标签: oracle plsql


【解决方案1】:

要捕获NO_DATA_FOUND 异常,请通过添加exception 部分重写您的代码,如下所示:

DECLARE
    VAR_SUPP_NM VARCHAR2(100);
    VAR_SUPP_ID  NUMBER := 1;
    WHILE_VAR CHAR := 'Y';
BEGIN
  SELECT SUPP_NM
    INTO VAR_SUPP_NM
    FROM TEST.SUPPLIER
   WHERE SUPP_ID = VAR_SUPP_ID;

 DBMS_OUTPUT.PUT_LINE('DATA FOUND');

exception
  when no_data_found 
  then DBMS_OUTPUT.PUT_LINE('SQL DATA NOT FOUND');

END;

检查SQL%FOUND 或SQL%NOTFOUND 在select into 语句的情况下没有任何意义,因为如果select 语句没有返回任何行,它将总是引发no_data_found 异常,除非该select 语句调用聚合函数,如果未选择任何行,它将始终返回数据或 null。

不要使用varchar 数据类型,而是使用varchar2 数据类型。

【讨论】:

    【解决方案2】:

    如果您想使用SELECT INTO,Nicholas 的答案就是您想要的。但是,如果您能够使用%FOUND 或%NOTFOUND 更重要,请考虑使用光标FETCHing:

    DECLARE
        VAR SUPP_NM VARCHAR2(100);
        VAR_SUPP_ID  NUMBER := 1;
        WHILE_VAR CHAR := 'Y';
        CURSOR c1 IS
            SELECT SUPP_NM
            FROM TEST.SUPPLIER
            WHERE SUPP_ID = VAR_SUPP_ID;
    BEGIN
        OPEN c1;
        FETCH c1 INTO VAR_SUPP_NM;
    
        IF c1%NOTFOUND THEN
                DBMS_OUTPUT.PUT_LINE('SQL DATA NOT FOUND');
        ELSIF c1%FOUND THEN
                DBMS_OUTPUT.PUT_LINE('DATA FOUND');
        END IF;
    
        CLOSE c1;
    END;
    

    【讨论】:

      【解决方案3】:

      尼克的回答是正确的。

      然而,在 oracle 文档中指出 SQL%NOTFOUND 与 SELECT INTO 一起使用,但在检查 SQL%NOTFOUND 为 TRUE 之前,会生成一个错误,称为 no_data_found。

      所以要使用SQL%NOTFOUND,首先需要处理no_data_found错误。

      DECLARE
          VAR SUPP_NM VARCHAR(100);
          VAR_SUPP_ID  NUMBER := 1;
          WHILE_VAR CHAR := 'Y';
      BEGIN
          BEGIN
              SELECT SUPP_NM
              INTO VAR_SUPP_NM
              FROM TEST.SUPPLIER
              WHERE SUPP_ID = VAR_SUPP_ID;
      
              EXCEPTION 
                  WHEN NO_DATA_FOUND THEN
                      null; -- or write something here if u want.
          END;
          IF SQL%NOTFOUND THEN
              DBMS_OUTPUT.PUT_LINE('SQL DATA NOT FOUND');
          ELSIF SQL%FOUND THEN
              DBMS_OUTPUT.PUT_LINE('DATA FOUND');
          END IF;    
      END;
      

      所以我所做的是添加一个内部BEGIN-END 块,其中包含生成no_data_found 异常的SELECT 语句。之后你可以检查SQL%NOTFOUND的值。

      您可以在 oracle 文档中阅读有关此内容的更多信息。 从 mytime 中的这个活动链接开始:https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/errors.htm#LNPLS00703

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-19
        • 1970-01-01
        • 1970-01-01
        • 2014-06-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多