Oracle 不捕获异常
Oracle Doesn't Catch Exception
我在 Oracle 中有一个过程,我遇到了一个错误,但它没有更改 p_out_msg 的值,为什么会这样??错误转到光标处。
代码:
PROCEDURE get_proj(p_date IN VARCHAR2,
p_out_cur OUT sys_refcursor,
p_out_msg OUT VARCHAR2)
IS
BEGIN
OPEN p_out_cur FOR
SELECT *
FROM table t
WHERE TO_DATE(p_date, 'DD-MM-YYYY HH24:MI:SS') = t.date
p_out_msg := 'SUCCESS';
EXCEPTION
WHEN OTHERS THEN
p_out_msg := SUBSTR('An error was encountered: '||SQLERRM, 1, 250);
END get_proj;
假设我输入了无效日期:
输出:
p_out_cur: ORA-01858: a non-numeric character was found where a numeric was expected
p_out_msg: SUCCESS
这是@brenners1302
请求的匿名块:
DECLARE
P_DATE VARCHAR2(200);
P_OUT_CUR sys_refcursor;
P_OUT_MSG VARCHAR2(200);
BEGIN
P_DATE := '1111';
PACKAGE_TEST.GET_PROJ(
P_DATE => P_DATE,
P_OUT_CUR => P_OUT_CUR,
P_OUT_MSG => P_OUT_MSG
);
DBMS_OUTPUT.PUT_LINE(P_OUT_MSG); --SUCCESS
END;
当您使用 OPEN p_out_cur FOR
打开游标时,查询 SELECT * FROM ...
此刻并未执行,而只是与游标变量相关联。所以当你从p_out_cur
开始FETCH
时可能会出现异常,因为这是关联查询开始执行的时候。
查看它的最简单方法是以这种方式更改您的程序。
PROCEDURE get_proj(p_date IN VARCHAR2,
p_out_cur OUT sys_refcursor,
p_out_msg OUT VARCHAR2)
IS
l_rec myTable%ROWTYPE;
BEGIN
OPEN p_out_cur FOR
SELECT *
FROM myTable t
WHERE TO_DATE(p_date, 'DD-MM-YYYY HH24:MI:SS') = t.date
-- at this point we can get an exception
FETCH p_out_cur INTO l_rec;
p_out_msg := 'SUCCESS';
EXCEPTION
WHEN OTHERS THEN
p_out_msg := SUBSTR('An error was encountered: '||SQLERRM, 1, 250);
END get_proj;
所以是的,这意味着当您打开一个引用游标并将其传递给 'outer world' 时,试图获取它的人可能会遇到异常。在将参数传递给与游标关联的 SQL 中使用的函数之前,您可以通过检查参数来减少此类情况的数量。例如,
PROCEDURE get_proj(p_date IN VARCHAR2,
p_out_cur OUT sys_refcursor,
p_out_msg OUT VARCHAR2)
IS
l_normal_date DATE;
BEGIN
-- if p_date has wrong format we better find it out
-- before using it in a query
l_normal_date := TO_DATE(p_date, 'DD-MM-YYYY HH24:MI:SS');
OPEN p_out_cur FOR
SELECT *
FROM myTable t
WHERE l_normal_date = t.date
p_out_msg := 'SUCCESS';
EXCEPTION
WHEN OTHERS THEN
p_out_msg := SUBSTR('An error was encountered: '||SQLERRM, 1, 250);
END get_proj;
我在 Oracle 中有一个过程,我遇到了一个错误,但它没有更改 p_out_msg 的值,为什么会这样??错误转到光标处。
代码:
PROCEDURE get_proj(p_date IN VARCHAR2,
p_out_cur OUT sys_refcursor,
p_out_msg OUT VARCHAR2)
IS
BEGIN
OPEN p_out_cur FOR
SELECT *
FROM table t
WHERE TO_DATE(p_date, 'DD-MM-YYYY HH24:MI:SS') = t.date
p_out_msg := 'SUCCESS';
EXCEPTION
WHEN OTHERS THEN
p_out_msg := SUBSTR('An error was encountered: '||SQLERRM, 1, 250);
END get_proj;
假设我输入了无效日期:
输出:
p_out_cur: ORA-01858: a non-numeric character was found where a numeric was expected
p_out_msg: SUCCESS
这是@brenners1302
请求的匿名块:
DECLARE
P_DATE VARCHAR2(200);
P_OUT_CUR sys_refcursor;
P_OUT_MSG VARCHAR2(200);
BEGIN
P_DATE := '1111';
PACKAGE_TEST.GET_PROJ(
P_DATE => P_DATE,
P_OUT_CUR => P_OUT_CUR,
P_OUT_MSG => P_OUT_MSG
);
DBMS_OUTPUT.PUT_LINE(P_OUT_MSG); --SUCCESS
END;
当您使用 OPEN p_out_cur FOR
打开游标时,查询 SELECT * FROM ...
此刻并未执行,而只是与游标变量相关联。所以当你从p_out_cur
开始FETCH
时可能会出现异常,因为这是关联查询开始执行的时候。
查看它的最简单方法是以这种方式更改您的程序。
PROCEDURE get_proj(p_date IN VARCHAR2,
p_out_cur OUT sys_refcursor,
p_out_msg OUT VARCHAR2)
IS
l_rec myTable%ROWTYPE;
BEGIN
OPEN p_out_cur FOR
SELECT *
FROM myTable t
WHERE TO_DATE(p_date, 'DD-MM-YYYY HH24:MI:SS') = t.date
-- at this point we can get an exception
FETCH p_out_cur INTO l_rec;
p_out_msg := 'SUCCESS';
EXCEPTION
WHEN OTHERS THEN
p_out_msg := SUBSTR('An error was encountered: '||SQLERRM, 1, 250);
END get_proj;
所以是的,这意味着当您打开一个引用游标并将其传递给 'outer world' 时,试图获取它的人可能会遇到异常。在将参数传递给与游标关联的 SQL 中使用的函数之前,您可以通过检查参数来减少此类情况的数量。例如,
PROCEDURE get_proj(p_date IN VARCHAR2,
p_out_cur OUT sys_refcursor,
p_out_msg OUT VARCHAR2)
IS
l_normal_date DATE;
BEGIN
-- if p_date has wrong format we better find it out
-- before using it in a query
l_normal_date := TO_DATE(p_date, 'DD-MM-YYYY HH24:MI:SS');
OPEN p_out_cur FOR
SELECT *
FROM myTable t
WHERE l_normal_date = t.date
p_out_msg := 'SUCCESS';
EXCEPTION
WHEN OTHERS THEN
p_out_msg := SUBSTR('An error was encountered: '||SQLERRM, 1, 250);
END get_proj;