【问题标题】:PL/SQL Function returned without valuePL/SQL 函数返回无值
【发布时间】:2013-02-26 09:02:23
【问题描述】:

我写在下面FUNCTION 以检查给定的reference number 是否存在。

FUNCTION find_reference_no(
    p_ref_no IN VARCHAR2) RETURN VARCHAR2
AS

  v_ref_no varchar2(50);

BEGIN

  select REF_NO into v_ref_no from cash where REF_NO = p_ref_no;  
  EXCEPTION
    WHEN no_data_found THEN
    v_ref_no := '#';

RETURN v_ref_no;    

END;

我在AFTER INSERT TRIGGER 中调用了这个函数。当我插入数据时,我收到错误

ORA-06503: PL/SQL: Function returned without value

我该如何解决这个问题?

PS:我没有将数据插入到cash 表中。我正在将数据插入另一个表(假设它是表 B)并在它的(表 B)AFTER INSERT TRIGGER 中调用此函数。

【问题讨论】:

  • 这种在触发器中的查找正是我们应该避免在触发器中进行的那种。这是每次插入时的隐藏性能,并且会损害应用程序的可伸缩性。
  • 不要在参数名称前加上 p_ 前缀,而是考虑在查询中的参数名称前加上函数名称——即。 “其中 cash.ref_no = find_reference_no.ref_no”。 v_ 作为变量的前缀也是多余的,它也应该是数据类型为 cash.ref_no%Type 而不是 varchar2(50)。
  • 问题不明显的原因是您的代码格式具有误导性 - RETURN 语句 看起来 是函数正常处理的一部分,而实际上它在函数的异常块。 EXCEPTION 关键字实际上应该位于左边距,与 BEGIN 和 END 处于同一级别 - 为清楚起见。

标签: oracle function plsql oracle11g


【解决方案1】:

由于该函数只返回与表中存在的参数相同的值,因此您可以避免使用异常处理并将其重写为:

  function find_reference_no(
      ref_no in varchar2)
  return varchar2
  as
    row_count integer
  begin
    select count(*)
    into   row_count
    from   cash
    where  cash.ref_no = find_reference_no.ref_no and
           rownum      = 1

    if row_count = 0
      return '#'
    else
      return ref_no
    end if;

  end find_reference_no;

我会返回一个 1 或 0(即 row_count 的值)来表示该记录存在或不存在。

  function find_reference_no(
      ref_no in varchar2)
  return varchar2
  as
    row_count integer
  begin
    select count(*)
    into   row_count
    from   cash
    where  cash.ref_no = find_reference_no.ref_no and
           rownum      = 1

    return row_count

  end find_reference_no;

【讨论】:

    【解决方案2】:

    所有函数都必须执行 RETURN 语句。您的函数在其异常块中有 RETURN,因此该语句在正常情况下不会被执行。

    通过附加的begin end 块将select 语句与它自己的exception 部分括起来将解决您的问题。所以你的函数可能看起来像这样:

    create or replace function find_reference_no(
        p_ref_no IN VARCHAR2) return varchar2
    AS
      v_ref_no varchar2(50);
    begin
      begin
        select REF_NO 
           into v_ref_no 
           from cash 
          where REF_NO = p_ref_no;  
      exception
         WHEN no_data_found THEN
              v_ref_no := '#';
       end;
      return v_ref_no;    
    end;
    

    【讨论】:

      猜你喜欢
      • 2013-05-06
      • 1970-01-01
      • 2016-12-27
      • 2014-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-22
      相关资源
      最近更新 更多