执行该函数后,sql命令未正确结束

时间:2015-01-17 08:53:50

标签: oracle plsql oracle11g

例如我创建了一个表名为'aaa'的表,其中有四列act_num,clear_balance,available_balance,total_balance,我已经插入了一些值。

功能 deb_amount从银行账户中提取资金。它接受一个帐户 数量和金额作为参数。它使用帐号来 从数据库中检索帐户余额,然后计算新余额。如果这 新余额小于零,然后函数跳转到错误例程;除此以外, 它会更新银行帐户。

create or replace function deb_amount(p_act_num VARCHAR2, p_amount number ) 
return number as 

declare
v_old_amount number;
v_new_amount number;
e_over_drawn exception;

begin
select clear_balance into v_old_amount from aaa where act_num=p_act_num;
v_new_amount:=v_old_amount-p_amount;   
 if v_old_amount<p_amount then
        raise e_over_drawn;
            else
                update aaa set clear_balance=v_new_amount,available_balance=v_new_amount,total_balance=v_new_amount where act_num=p_act_num;
                end if;
                commit;
                return clear_balance;
        exception
        when e_over_drawn then
        rollback;
        end;

它会编译,但有警告。

如果我想执行'select * from deb_amount(1,100)'则显示错误。 sql命令没有正确结束。

谢谢。

2 个答案:

答案 0 :(得分:2)

你需要使用dual来调用函数。例如:

select deb_amount(1,100) from dual;

或在plsql块中使用变量

declare
  l_return number; 
begin 
  l_return:=deb_amount(1,100);
end;

答案 1 :(得分:1)

看起来您可能正在运行几个命令作为一个scipt,但还没有正确地结束该功能。函数创建后的/必须自己在一行上,并在行的开头:

create or replace function deb_amount(p_act_num VARCHAR2,
  p_amount number) 
  return number as 
declare
  v_old_amount number;
  v_new_amount number;
  e_over_drawn exception;
begin
  select clear_balance into v_old_amount
  from aaa where act_num=p_act_num;
  v_new_amount:=v_old_amount-p_amount;   
  if v_old_amount<p_amount then
    raise e_over_drawn;
  else
    update aaa set clear_balance=v_new_amount,
      available_balance=v_new_amount,
      total_balance=v_new_amount
    where act_num=p_act_num;
  end if;
  commit;
  return clear_balance;
exception
  when e_over_drawn then
    rollback;
end;
/
show errors

select deb_account('1', 1) from dual;

show errors将告诉您实际编译错误。看起来它会抱怨return,因为您没有本地clear_balance变量,但您可以在此处使用v_new_amount。你需要在rollback之后返回一些东西,或者提出一个可能更有用的异常。

正如Manjunatha所说,你的查询需要正确调用函数,from子句引用一个表,而不是函数本身。

你对这个概念有一个更大的问题;你不能只从PL / SQL块调用从SQL执行DML(插入,更新,删除)的函数。一般来说,DML应该从一个过程而不是一个函数完成,如果必须在PL / SQL中完成的话。