gho*_*der 0 sql oracle plsql stored-procedures user-defined-functions
UDF和SP之间的主要区别之一是UDF只能在其中包含select语句而不能插入/更新/删除语句.有人可以解释一下这背后的原因吗?以下功能:
create function test(..)
...
BEGIN
insert into EMPLOYEE('22',12000,'john');
return 0;
END
Run Code Online (Sandbox Code Playgroud)
无效.但为什么会这样呢?
函数内的insert语句缺少values关键字;
insert into EMPLOYEE('22',12000,'john');
Run Code Online (Sandbox Code Playgroud)
应该
insert into EMPLOYEE values ('22',12000,'john');
Run Code Online (Sandbox Code Playgroud)
虽然最好也包括列名列表.从您展示的代码的一小部分来看,这是唯一无效的.您省略的位可能存在其他错误.(如果表中的第一列是数字,那么你不应该传递一个字符串 - 它可以工作,但是进行隐式转换,最好避免.如果列是一个字符串,它应该是真的吗?)
UDF只能在其中包含select语句而不能插入/更新/删除语句
这是不正确的.您可以在函数中使用DML(插入/更新/删除),但是您只能从PL/SQL上下文中调用它(尽管在PL/SQL中,通常会说函数应该查询数据而没有副作用,只有程序应修改数据;但不受语言本身的限制):
create table employee (id varchar2(3), salary number, name varchar2(10));
Table EMPLOYEE created.
create function test(unused number)
return number as
BEGIN
insert into EMPLOYEE (id, salary, name)
values ('22',12000,'john');
return 0;
END;
/
Function TEST compiled
declare
rc number;
begin
rc := test(42);
end;
/
PL/SQL procedure successfully completed.
select * from employee;
ID SALARY NAME
--- ---------- ----------
22 12000 john
Run Code Online (Sandbox Code Playgroud)
但是你不能从SQL上下文中调用它:
select test(42) from dual;
ORA-14551: cannot perform a DML operation inside a query
ORA-06512: at "MYSCHEMA.TEST", line 4
Run Code Online (Sandbox Code Playgroud)
该文档列出了对从SQL调用的函数的限制,并在此警告中详细介绍:
因为SQL是一种声明性语言,而不是命令式(或程序性)语言,所以你无法知道SQL语句调用的函数将运行多少次 - 即使该函数是用PL/SQL(一种命令式语言)编写的.
如果允许该函数执行DML,那么您将无法控制执行DML的次数.例如,如果它正在进行插入,它可能会尝试两次插入相同的行并重复数据或获取约束违规.
| 归档时间: |
|
| 查看次数: |
452 次 |
| 最近记录: |