CREATE OR REPLACE FUNCTION get_status_by_member_id
(p_member_id NUMBER)
RETURN CHAR
AS
v_status CHAR(1);
BEGIN
select status
into v_status
from members
where member_id = p_member_id;
if v_status is null then
return v_status || 'N';
else
return v_status;
end if;
END get_status_by_member_id;
user1598538
问问题
2216 次
2 回答
6
您的问题有时是由 Oracle 的一个恼人的怪癖引起的。也就是说,如果在 SQL 中调用 PL/SQL 函数并返回错误,则null
返回,而不是其他任何内容。
如果我创建一个非常简单的表......
create table a ( b number, c varchar2(1) );
insert into a values (1,'Y');
...和两个功能。一种没有异常处理
create or replace function tmp_ben_fn (PId number) return char is
l_status varchar2(1);
begin
select c
into l_status
from a
where b = PId;
return coalesce(l_status, 'N');
end;
/
一个具有异常处理功能。
create or replace function tmp_ben_fn2 (PId number) return char is
l_status varchar2(1);
begin
select c
into l_status
from a
where b = PId;
return coalesce(l_status, 'N');
exception when no_data_found then
return 'A';
end;
/
然后,我们使用这两个函数来选择数据。请记住,我们只有一行,所以我们只期望Y
或被N
返回:
SQL> -- Expected output Y
SQL> select tmp_ben_fn(1) from dual;
TMP_BEN_FN2(1)
-------------------------------------------------
Y
SQL> -- Expected output, Error no_data_found
SQL> -- as row 2 does not exist.
SQL> select tmp_ben_fn(2) from dual;
TMP_BEN_FN(2)
-------------------------------------------------
SQL> -- Expected output, the same as tmp_ben_fn
SQL> select tmp_ben_fn2(2) from dual;
TMP_BEN_FN2(2)
-------------------------------------------------
A
SQL>
正如您在没有错误处理的函数中看到的那样,当发生no_data_found
异常时null
会返回 a 。当我们捕获异常时,我们得到的是预期的A
。
我怀疑member_id
您尝试选择的 不存在。
作为一般规则:始终注意何时可能发生异常,select into...
这是一个特别令人担忧的例子,有机会选择太多行和没有行。如果您的表是唯一的,member_id
那么您应该按如下方式更改您的功能:
CREATE OR REPLACE FUNCTION get_status_by_member_id (p_member_id NUMBER)
RETURN CHAR IS
v_status CHAR(1);
BEGIN
select status
into v_status
from members
where member_id = p_member_id;
return v_status;
-- If the member_id does not exist
-- return N
exception when no_data_found then
return 'N';
END get_status_by_member_id;
于 2012-08-14T17:07:05.130 回答
2
尝试在代码中添加异常处理程序,如下所示:
CREATE OR REPLACE FUNCTION get_status_by_member_id
(p_member_id NUMBER) RETURN CHAR
as
v_status CHAR(1);
begin
BEGIN
select status
into v_status
from members
where member_id = p_member_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
v_status := NULL;
WHEN TOO_MANY_ROWS THEN
v_status := NULL;
END;
if v_status is null then
return 'N';
else
return v_status;
end if;
end get_status_by_member_id;
这将处理没有与 p_member_id 匹配的数据或有多个行与 p_member_id 匹配的情况。这可能会或可能不会纠正您看到的问题。如果您编辑您的帖子并添加您正在使用 which calls 的代码,这将很有帮助get_status_by_member_id
。
分享和享受。
于 2012-08-14T16:46:10.313 回答