我一直在查看预定义的 Oracle pl/SQL Exceptions。我想在找到数据时引发异常。我已经能够看到 NO_DATA_FOUND
异常(exception)。但不是相反。执行此操作的最佳方法是什么,或者不建议执行此类操作。
我的程序如下
PROCEDURE CHECK_ASSIGNED AS
PLACEHOLDER INT;
BEGIN
SELECT v.id
INTO PLACEHOLDER
FROM vinegar v
WHERE NOT EXISTS (
SELECT 1
FROM home h
WHERE h.sid = v.sid
)
END;
-- when data is found it means that and sid does not exist in the home table
-- should raise exception and stop package
最佳答案
“找到的数据”没有内置错误,因为 Oracle 不会将查找数据视为错误。但是,在特定情况下将这种情况视为错误并不太难。
这在某种程度上取决于您想对异常做什么。如果您想在过程中以某种方式对其使用react,您可以定义自己的异常,然后引发它:
PROCEDURE check_assigned AS
exception err_data_found;
placeholder INT;
BEGIN
SELECT v.id
INTO placeholder
FROM vinegar v
WHERE NOT EXISTS
(SELECT 1
FROM home h
WHERE h.sid = v.sid);
IF SQL%FOUND THEN
RAISE err_data_found;
END IF;
EXCEPTION
WHEN err_data_found THEN
NULL;
--do something
END;
另一方面,如果你只是想把错误返回给调用者,你可以使用
raise_application_error
:PROCEDURE check_assigned AS
placeholder INT;
BEGIN
SELECT v.id
INTO placeholder
FROM vinegar v
WHERE NOT EXISTS
(SELECT 1
FROM home h
WHERE h.sid = v.sid);
IF SQL%FOUND THEN
raise_application_error (-20001,
'Data was found in the vinegar table.');
END IF;
END;
如果目标是在任何行存在时引发错误,否则继续,这样做有点危险,因为你有触发
NO_DATA_FOUND
的风险。或 TOO_MANY_ROWS
.您可以通过选择评论中建议的计数来解决这个问题,但我更喜欢使用显式光标来避免这些问题。PROCEDURE check_assigned AS
placeholder INT;
CURSOR cur_vinegar_check IS
SELECT v.id
INTO placeholder
FROM vinegar v
WHERE NOT EXISTS
(SELECT 1
FROM home h
WHERE h.sid = v.sid)
AND ROWNUM = 1;
BEGIN
OPEN cur_vinegar_check;
FETCH cur_vinegar_check INTO placeholder;
IF SQL%FOUND THEN
raise_application_error (-20001,
'Data was found in the vinegar table.');
END IF;
CLOSE cur_vinegar_check;
END check_assigned;
你会注意到我添加了
AND ROWNUM = 1
到查询。这是rownum
为数不多的几次之一在外部查询中是可预测的:您只关心一行是否存在;你不在乎它是哪一行。如果您有可能返回大量行,这会带来显着的性能优势。
关于exception - 找到数据时PL SQL引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27971939/