pl sql %NOTFOUND

Posted

技术标签:

【中文标题】pl 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 不起作用?

【问题讨论】:

请将该信息编辑到您的问题中。 (并且总是在发布问题时直接在问题中准确说出正在发生的事情/将来会遇到什么错误。这非常重要。) 【参考方案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%FOUNDSQL%NOTFOUNDselect 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%NOTFOUNDSELECT 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

【讨论】:

以上是关于pl sql %NOTFOUND的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL编程

PL/SQL简介

PL/SQL编程_存储程序

PL/SQL:无法从包元素 PL/SQL 返回值

PL/SQL 编程

Mysql、SQL server有没有PL/SQL?或者是类似PL/SQL的东西?PL/SQL是否存储过程?