2016-08-03 60 views
-3

我有非常简单的功能,我只是想根据传递的参数更新salary列。我知道我可以通过程序来完成,但是这个代码有什么问题,请有谁能解释我。简单功能没有按预期工作

表和数据结构:

create table emp_test (emp_id number, salary number); 
insert into emp_test values (10,750); 
insert into emp_test values (11,850); 
insert into emp_test values (12,650); 
insert into emp_test values (13,950); 
insert into emp_test values (14,1750); 
insert into emp_test values (15,2750); 

和函数:

CREATE OR REPLACE FUNCTION 
CIS_EXT.UPDATE_EMP_SAL(p_emp_id IN emp_test.emp_id%TYPE) 
return NUMBER 
IS 
BEGIN 
    UPDATE EMP_TEST SET SALARY = SALARY+200 
    WHERE EMP_ID = p_emp_id; 
    COMMIT; 
    RETURN 1; 
EXCEPTION 
    WHEN OTHERS THEN 
    RETURN 0; 
END UPDATE_EMP_SAL ; 

当我运行像下面

SELECT UPDATE_EMP_SAL(10) FROM DUAL; 

我的输出来0.为什么呢?

+2

帮助中心拥有[如何格式化您的文章一节(http://stackoverflow.com/help/格式化) –

回答

3

您正在隐藏您的when others异常处理程序的实际错误。 That is almost always a bug;你所做的只是压制有用的信息,并让调用者认为一切正常,除非他们碰巧知道要检查(以及如何解释)返回值。最好不要在这里处理意外的异常,并让调用者在看到它时决定该做什么。 (最好不要在一个过程/函数中提交或回滚,因为它可能会中断调用者的事务,但这是一个单独的问题)。

如果删除异常处理程序,你会看到,它说:

ORA-14551: cannot perform a DML operation inside a query 

是错误的描述是:

*原因:像INSERT,UPDATE DML操作,删除或选择更新
不能在查询内部或PDML从站内执行。
*操作:确保未执行违规的DML操作或使用自主事务在查询或PDML从机的
内执行DML操作。

它允许一个函数来执行DML,尽管它通常只能在过程中执行DML。但是如果你的函数不会做DML,你只能再从PL叫它/ SQL:

set serveroutput on 
declare 
    rc number; 
begin 
    rc := UPDATE_EMP_SAL(10); 
    dbms_output.put_line(rc); 
end; 
/

PL/SQL procedure successfully completed. 

1 

select * from emp_test where emp_id = 10; 

    EMP_ID  SALARY 
---------- ---------- 
     10  950 
+0

感谢亚历克斯,它的工作原理, – Sohel

+0

@Sohel如果它的工作,你应该将它标记为答案 – vercelli

+0

我将如何标记为答案 – Sohel