Oracle SQL:为什么我的函数输出 null


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;

您的问题是由有时令人讨厌的 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;
/

然后,我们使用这两个函数来选择数据。请记住,我们只有一行,因此我们预计只会返回YN

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

我怀疑您尝试选择的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;

尝试向代码添加异常处理程序,如下所示:

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匹配的情况。 这可能会也可能不会纠正您看到的问题。 如果您编辑帖子并添加您正在使用的代码,这将很有帮助 调用get_status_by_member_id .

分享和享受。

最新更新