带有 SQL%NOTFOUND 的 PL/SQL raise_application_error

Posted

技术标签:

【中文标题】带有 SQL%NOTFOUND 的 PL/SQL raise_application_error【英文标题】:PL/SQL raise_application_error with SQL%NOTFOUND 【发布时间】:2015-01-28 18:25:59 【问题描述】:

我正在尝试编写一个程序来检查我的某些表中的人员是否被正确分配。这是包中的第一个过程。如果每个人都被正确分配,SQL 将不返回任何记录。如果未分配人员,SQL 将返回未分配的人员。

...

BEGIN

    FOR R_PEOPLE IN C_PEOPLE

        LOOP

        IF SQL%NOTFOUND THEN
            RAISE_APPLICATION_ERROR(-20002, 'ALL PEOPLE ASSIGNED, PROCEED');
        END IF;

       -- When data is found, should raise exception and stop billing process

        IF SQL%FOUND THEN
            RAISE_APPLICATION_ERROR(-20001, 'MISSING PEOPLE');
        END IF;

        END LOOP;

END;

我要做的是向最终用户发出两条不同的消息,最终用户将在TOAD 中运行它。如果没有返回结果,每个人都被分配,我想输出第一个IF 语句“ALL PEOPLE ASSIGNED, PROCEED”。如果 SQL 返回记录,那么理想情况下,我希望第二个 IF 执行“MISSING People”。

目前,当有人失踪时,我会向用户输出“MISSING PEOPLE”。但是如果每个人都已经被分配,我只会得到“程序完成”。

【问题讨论】:

【参考方案1】:
FOR R_PEOPLE IN C_PEOPLE

    LOOP

    IF SQL%NOTFOUND THEN
    -- ^^^^^^^^^^^^
    -- this can never be true since if there was no row,
    -- you won't enter the loop
        RAISE_APPLICATION_ERROR(-20002, 'ALL PEOPLE ASSIGNED, PROCEED');
    END IF;

    ...

这是行不通的,因为如果没有匹配,你甚至不会执行一次循环体。


我不知道您的查询如何,但也许您可以使用COUNT(*) 重写它并使用结果(0 或非零)来引发适当的异常?

类似的东西,也许:

SELECT COUNT(*) INTO RESULT FROM .... WHERE ..... ;
IF RESULT = 0
THEN
    RAISE_APPLICATION_ERROR(-20002, 'ALL PEOPLE ASSIGNED, PROCEED');
ELSE
    RAISE_APPLICATION_ERROR(-20001, 'MISSING PEOPLE');
END IF;

【讨论】:

我可以重写它,是的,最初它只是返回最高的 person_id。所以这不会是一件麻烦事。谢谢 RESULT == 0,应该是= 0(我认为) @Jonnny Oups!语言错误。谢谢。

以上是关于带有 SQL%NOTFOUND 的 PL/SQL raise_application_error的主要内容,如果未能解决你的问题,请参考以下文章

当 PL/SQL 中的 %NOTFOUND 为 NULL [重复]

pl sql %NOTFOUND

PL/SQL 游标的使用详解

带有动态 sql 的 PL/SQL 触发器

PL/SQL 04 游标 cursor

PL/SQL 如何创建字符串函数=