如何将no_data_found异常重写为用户自定义异常?
How to rewrite no_data_found exception into a user-defined exception?
这是捕获 Oracle 异常的代码
set serveroutput on;
ACCEPT identifiant PROMPT 'id';
DECLARE
vType PARCELLE.TypeP%Type;
vSuperf PARCELLE.Superf%Type;
BEGIN
SELECT distinct TypeP,Superf INTO vType,vSuperf
FROM PARCELLE
WHERE PARCELLE.NumPropC='&identifiant'
AND Superf=(select MAX(Superf) from PARCELLE
where PARCELLE.NumPropC='&identifiant');
DBMS_OUTPUT.PUT_LINE('id:'||'&identifiant'||',type:'||vType
||',Supeficie:'||vSuperf);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('Aucun Propriétaire vous cherchez.');
END;
我现在需要做的是编写另一个版本,不使用内置异常,而是使用用户定义的异常。结果应该是一样的。
我试过这样的东西
BEGIN
SELECT distinct TypeP,Superf INTO vType,vSuperf
FROM PARCELLE
WHERE PARCELLE.NumPropC='&identifiant'
AND Superf=(select MAX(Superf) from PARCELLE
where PARCELLE.NumPropC='&identifiant');
IF vType IS NULL OR vSuperf IS NULL THEN RAISE non_trouve;
END IF;
DBMS_OUTPUT.PUT_LINE('id:'||'&identifiant'||',type:'||vType
||',Supeficie:'||vSuperf);
EXCEPTION
WHEN non_trouve THEN
dbms_output.put_line('Aucun Propriétaire vous cherchez.');
在达到跳转到异常的条件之前,它首先returns内置异常(未找到)。
我尝试了另一种方式:
DECLARE
vType PARCELLE.TypeP%Type;
vSuperf PARCELLE.Superf%Type;
non_trouve EXCEPTION;
vToutProp PROPRIETAIRE.NumPropC%TYPE;
BEGIN
SELECT * INTO vToutProp FROM PROPRIETAIRE;
IF '&identifiant' NOT IN (vToutProp) THEN RAISE non_trouve;
END IF;
--same left
但这是完全错误的,因为我应该声明一个数组或其他东西,但我不知道如何处理它。
有人有想法吗?
也许这会有所帮助。在 Oracle PL SQL 中,您可以创建自己的异常,如下所示
PROCEDURE ProcedureName
IS
CUSTOM_EXCEPTION EXCEPTION;
BEGIN
-- code here
RAISE CUSTOM_EXCEPTION
EXCEPTION
WHEN CUSTOM_EXCEPTION THEN
-- code for CUSTOM_EXCEPTION
END ProcedureName
由于不允许使用内置异常,请使用计数函数检查数据是否存在。如果不是,则引发自定义异常。
set serveroutput ON;
ACCEPT identifiant prompt 'id';
DECLARE
v_count NUMBER := 0;
e_non_trouve EXCEPTION;
BEGIN
SELECT Count(1)
INTO v_count
FROM parcelle
WHERE parcelle.numpropc = '&identifiant'
AND superf = (SELECT Max(superf)
FROM parcelle
WHERE parcelle.numpropc = '&identifiant');
IF v_count = 0 THEN
RAISE e_non_trouve;
END IF;
EXCEPTION
WHEN e_non_trouve THEN
dbms_output.Put_line('Aucun Propriétaire vous cherchez.');
END;
嗯,老实说,如果您要做的只是像在示例代码中那样吸收异常,那么您不会 "need to do now" 做任何此类事情。在我的脑海中,我只能想到使用用户定义异常的两个原因:
- 您想在过程外传播异常,并且希望它对调用者有意义。所以你想把 "no data found" 变成 "that student is not currently enrolled in that class."
- 过程中有几个位置可能引发 "no data found" 异常,但重要性(以及含义)因引发的位置而异。您希望外层异常处理程序能够辨别差异。
如果是第二个选项,做这样的事情可能同样好或更好:
err_code := 1;
-- perform something that might raise no_data_found
...
err_code := 2;
-- perform something else that might raise no_data_found
...
err_code := 3;
-- perform something else that might raise no_data_found
...
exception
when no_data_found then
if err_code = 1 then
Raise_application_error( -20001, 'Student not enrolled in that class';
elsif err_code = 2 then
Raise_application_error( -20001, 'Student not making a passing grade in class';
elsif err_code = 3 then
Raise_application_error( -20001, 'Only you can prevent forest fires!';
end if;
when others then
-- uh-oh
end proc;
它并不花哨,但它完成了工作。
这是捕获 Oracle 异常的代码
set serveroutput on;
ACCEPT identifiant PROMPT 'id';
DECLARE
vType PARCELLE.TypeP%Type;
vSuperf PARCELLE.Superf%Type;
BEGIN
SELECT distinct TypeP,Superf INTO vType,vSuperf
FROM PARCELLE
WHERE PARCELLE.NumPropC='&identifiant'
AND Superf=(select MAX(Superf) from PARCELLE
where PARCELLE.NumPropC='&identifiant');
DBMS_OUTPUT.PUT_LINE('id:'||'&identifiant'||',type:'||vType
||',Supeficie:'||vSuperf);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('Aucun Propriétaire vous cherchez.');
END;
我现在需要做的是编写另一个版本,不使用内置异常,而是使用用户定义的异常。结果应该是一样的。
我试过这样的东西
BEGIN
SELECT distinct TypeP,Superf INTO vType,vSuperf
FROM PARCELLE
WHERE PARCELLE.NumPropC='&identifiant'
AND Superf=(select MAX(Superf) from PARCELLE
where PARCELLE.NumPropC='&identifiant');
IF vType IS NULL OR vSuperf IS NULL THEN RAISE non_trouve;
END IF;
DBMS_OUTPUT.PUT_LINE('id:'||'&identifiant'||',type:'||vType
||',Supeficie:'||vSuperf);
EXCEPTION
WHEN non_trouve THEN
dbms_output.put_line('Aucun Propriétaire vous cherchez.');
在达到跳转到异常的条件之前,它首先returns内置异常(未找到)。
我尝试了另一种方式:
DECLARE
vType PARCELLE.TypeP%Type;
vSuperf PARCELLE.Superf%Type;
non_trouve EXCEPTION;
vToutProp PROPRIETAIRE.NumPropC%TYPE;
BEGIN
SELECT * INTO vToutProp FROM PROPRIETAIRE;
IF '&identifiant' NOT IN (vToutProp) THEN RAISE non_trouve;
END IF;
--same left
但这是完全错误的,因为我应该声明一个数组或其他东西,但我不知道如何处理它。
有人有想法吗?
也许这会有所帮助。在 Oracle PL SQL 中,您可以创建自己的异常,如下所示
PROCEDURE ProcedureName
IS
CUSTOM_EXCEPTION EXCEPTION;
BEGIN
-- code here
RAISE CUSTOM_EXCEPTION
EXCEPTION
WHEN CUSTOM_EXCEPTION THEN
-- code for CUSTOM_EXCEPTION
END ProcedureName
由于不允许使用内置异常,请使用计数函数检查数据是否存在。如果不是,则引发自定义异常。
set serveroutput ON;
ACCEPT identifiant prompt 'id';
DECLARE
v_count NUMBER := 0;
e_non_trouve EXCEPTION;
BEGIN
SELECT Count(1)
INTO v_count
FROM parcelle
WHERE parcelle.numpropc = '&identifiant'
AND superf = (SELECT Max(superf)
FROM parcelle
WHERE parcelle.numpropc = '&identifiant');
IF v_count = 0 THEN
RAISE e_non_trouve;
END IF;
EXCEPTION
WHEN e_non_trouve THEN
dbms_output.Put_line('Aucun Propriétaire vous cherchez.');
END;
嗯,老实说,如果您要做的只是像在示例代码中那样吸收异常,那么您不会 "need to do now" 做任何此类事情。在我的脑海中,我只能想到使用用户定义异常的两个原因:
- 您想在过程外传播异常,并且希望它对调用者有意义。所以你想把 "no data found" 变成 "that student is not currently enrolled in that class."
- 过程中有几个位置可能引发 "no data found" 异常,但重要性(以及含义)因引发的位置而异。您希望外层异常处理程序能够辨别差异。
如果是第二个选项,做这样的事情可能同样好或更好:
err_code := 1;
-- perform something that might raise no_data_found
...
err_code := 2;
-- perform something else that might raise no_data_found
...
err_code := 3;
-- perform something else that might raise no_data_found
...
exception
when no_data_found then
if err_code = 1 then
Raise_application_error( -20001, 'Student not enrolled in that class';
elsif err_code = 2 then
Raise_application_error( -20001, 'Student not making a passing grade in class';
elsif err_code = 3 then
Raise_application_error( -20001, 'Only you can prevent forest fires!';
end if;
when others then
-- uh-oh
end proc;
它并不花哨,但它完成了工作。