pl sql%NOTFOUND

时间:2012-10-25 19:09:51

标签: oracle plsql

我只是想知道为什么这段代码不起作用。我的表中没有供应商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;

3 个答案:

答案 0 :(得分:15)

通过添加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%NOTFOUNDselect into没有意义,因为如果select语句没有返回任何行,它将始终引发no_data_found异常,除了,如果select语句调用聚合函数,它将始终返回数据,如果没有选择行,则返回null。

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

答案 1 :(得分:3)

如果你想使用SELECT INTO,尼古拉斯的回答就是你想要的。但是,如果您能够使用%FOUND%NOTFOUND更为重要,请考虑使用光标FETCH

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;

答案 2 :(得分:2)

尼克的答案是正确的。

然而,在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块,该块封闭了生成SELECT异常的no_data_found语句。之后,您可以检查SQL%NOTFOUND的值。

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