从SQL语句调用带有to_char的PL / SQL函数

时间:2013-05-31 09:44:59

标签: oracle plsql oracle11g

我已经构建了这个函数来打印所有项目的列表以及每个项目的总承诺量。我需要格式化输出以显示$符号,逗号和值的两个小数位。

到目前为止,我可以得到结果,但没有格式化。我在函数中包含了to_char

当我调用它时,我收到此错误:

ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at "SYSTEM.DD_PROJECT_SF", line 19
06502. 00000 -  "PL/SQL: numeric or value error%s"
*Cause:    

*动作:

这是我的功能:

create or replace function DD_PROJECT_SF (

project_id dd_project.idproj%type)

return number is 

pledge_amount dd_pledge.pledgeamt%type;
project_name  dd_project.projname%type;
projid     dd_pledge.idproj%type;

begin 

select idproj, projname into   projid, project_name from  dd_project

where idproj = project_id;

select to_char(sum(pledgeamt), '$9,990.99')  into pledge_amount from dd_pledge 
where idproj = project_id;

if (pledge_amount = 0) then
return 0;
else
return pledge_amount;
end if;

return pledge_amount;

end  DD_PROJECT_SF;

这是调用SQL语句:

select idproj, projname, DD_PROJECT_SF(idproj) from dd_project;

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

首先,您将返回一个数字并将varchar选择为数字变量。您需要所有数据类型都相同。当你想要返回一个字符时,可能更容易在数字中选择一个数字,然后在返回时将变量转换为字符。

其次,你在这里有很多不必要的代码。它可以简化为:

create or replace function DD_PROJECT_SF (
    Pproject_id dd_project.idproj%type 
    ) return varchar2 is 

   -- As you're summing you don-t know
   -- whether the sum will fit in the same
   -- data type so extend to the maximum
   pledge_amount number;

begin 

   -- select a number
   select sum(pledgeamt) into pledge_amount 
     from dd_pledge 
    where idproj = Pproject_id;

   -- return a character
   return to_char(pledge_amount, '$9,990.99');

end  DD_PROJECT_SF;

作为旁注,正如您在总结时,您如何知道最高金额将低于10,000美元?您可能希望对此进行扩展以考虑更大的数字。

最后,这是一种可以在SQL语句而不是PL / SQL中轻松完成的事情。如果可能,请考虑使用一个。


您评论过:

  

...我在这里使用了if语句,因为我希望函数能够显示给我   如果总数为0,则为零而不是null。因此,我如何将其包括在内   你的代码。我试过但没有成功

如果承诺的总和为0,则此函数将始终返回0.如果表中没有与此IDPROJ相关的数据,则将返回NULL。

就个人而言,如果是这种情况,我不会通过返回0来掩盖没有数据的事实。 NULL和0在逻辑上是不同的;如果你这样做,你会失去这种区别。

话虽如此,如果你总是想在没有数据的情况下返回0,那么你可以使用NVL()这样做。将您的退货声明更改为以下内容:

return to_char(nvl(pledge_amount, 0), '$9,990.99');