简体   繁体   中英

Raise exception in stored procedure based on view entries

I have a stored procedure. I would like to implement the below logic, which I have written in pseudocode.

If the below query has one of more entries:

SELECT
    NULL
FROM
    table1
WHERE
    condition
GROUP BY
    column
HAVING
    COUNT(1) > 1
UNION ALL
SELECT
    NULL
FROM
    table1 a
WHERE
    condition
    AND EXISTS (
        SELECT
            NULL
        FROM
            table2 b
        WHERE
            condition
    );

Then raise an exception and stop the stored procedure.

Let's do this with the sample emp/dept schema - just plug in your own statement for your use case. You do need to declare since in pl/sql you cannot "just select". You always need to select into a variable. I usually just select the number 1 into a dummy variable of type number. The trick is to raise the exception after the SELECT INTO and do nothing on NO_DATA_FOUND .

You can use named exceptions to distinguish different cases but since a no data found will throw an exception you have to do each of the cases in its own block. The cleanest is to handle all named exceptions in the final exception block.

DECLARE
  l_dummy NUMBER;
  king_exists EXCEPTION; 
  dave_exists EXCEPTION; 
BEGIN
  BEGIN
    SELECT 1 INTO l_dummy FROM emp WHERE ename = 'DAVE';
    RAISE dave_exists;
  EXCEPTION WHEN NO_DATA_FOUND THEN
    NULL;
  END;
  BEGIN
    SELECT 1 INTO l_dummy FROM emp WHERE ename = 'KING';
    RAISE king_exists;
  EXCEPTION WHEN NO_DATA_FOUND THEN
    NULL;
  END;
EXCEPTION 
  WHEN dave_exists THEN
    raise_application_error(-20000,'My expection error message');
  WHEN king_exists THEN
    raise_application_error(-20001,'King exists');
END;
/

Here is an example of raising an exception if a particular value is found from a query:

declare
    somevar dual.dummy%type;
begin
    select 'Y' into somevar
    from   dual;

    if somevar = 'Y' then
        raise_application_error(-20123, 'Hull breach on deck 15. Abandon ship.'); 
    end if;
end;

The "select from dual" can be any query, so feel free to substitute your unions and counts (though we should really stick to the standard count(*) , not count('Dracula') etc).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM