PL SQL 找到数据时引发异常
PL SQL Raise Exception when data found
我一直在查看预定义的 Oracle pl/SQL 异常。我想在找到数据时引发异常。我已经能够看到 NO_DATA_FOUND
异常。但事实并非如此。最好的方法是什么,或者不建议执行这种操作。
我的流程是这样的
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
"data found" 没有内置错误,因为 Oracle 不认为查找数据是错误。但是,在特定情况下将这种情况视为错误并不难。
这在某种程度上取决于您要对异常执行的操作。如果你想在过程中以某种方式对它做出反应,你可以定义你自己的异常,然后引发它:
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;
另一方面,如果您只想return将错误告知调用者,您可以使用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
在外部查询中可预测的少数情况之一:您所关心的只是一行是否存在;你不在乎它在哪一行。如果您有可能得到很多行 returned,这会带来显着的性能优势。
您可以引发用户定义的异常。
PROCEDURE CHECK_ASSIGNED AS
PLACEHOLDER INT;
custom_exception EXCEPTION;
BEGIN
SELECT v.id
INTO PLACEHOLDER
FROM vinegar v
WHERE NOT EXISTS (
SELECT 1
FROM home h
WHERE h.sid = v.sid
)
if PLACEHOLDER is not null
then
raise custom_exception;
end if;
exception
when custom_exception
then
--do whatever exception stuff you want here
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
我一直在查看预定义的 Oracle pl/SQL 异常。我想在找到数据时引发异常。我已经能够看到 NO_DATA_FOUND
异常。但事实并非如此。最好的方法是什么,或者不建议执行这种操作。
我的流程是这样的
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
"data found" 没有内置错误,因为 Oracle 不认为查找数据是错误。但是,在特定情况下将这种情况视为错误并不难。
这在某种程度上取决于您要对异常执行的操作。如果你想在过程中以某种方式对它做出反应,你可以定义你自己的异常,然后引发它:
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;
另一方面,如果您只想return将错误告知调用者,您可以使用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
在外部查询中可预测的少数情况之一:您所关心的只是一行是否存在;你不在乎它在哪一行。如果您有可能得到很多行 returned,这会带来显着的性能优势。
您可以引发用户定义的异常。
PROCEDURE CHECK_ASSIGNED AS
PLACEHOLDER INT;
custom_exception EXCEPTION;
BEGIN
SELECT v.id
INTO PLACEHOLDER
FROM vinegar v
WHERE NOT EXISTS (
SELECT 1
FROM home h
WHERE h.sid = v.sid
)
if PLACEHOLDER is not null
then
raise custom_exception;
end if;
exception
when custom_exception
then
--do whatever exception stuff you want here
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;