我已经创建了常规功能。它已成功创建。但是当我用
运行它时select reg('awlad','01968688680','545466455','12345') from dual
它给了我这个错误:
ORA-14551: cannot perform a DML operation inside a query
我该如何解决这个问题?
CREATE OR REPLACE FUNCTION reg(
name in varchar2,
cellNo in varchar2,
voterId in varchar2,
pass in varchar2
)
RETURN NUMBER
IS
succ NUMBER;
BEGIN
succ:=0;
insert into logInfo values(loginfo_seq.nextval,cellNo,pass,0);
succ:=1;
insert into passInfo values(name,cellNo,voterId);
succ:=2;
RETURN succ;
END;
答案 0 :(得分:6)
一个函数应该计算并返回一个结果,而不是改变数据库的状态。如果要在函数中执行DML
(即,如果要在表中插入行),则无法在SELECT
语句中调用该函数,因为SELECT
语句无法更改状态的数据库。一般来说,最好将这种东西创建为存储过程而不是存储函数。
您可以像调用存储过程一样从PL / SQL块调用此函数
DECLARE
l_success_code NUMBER;
BEGIN
l_success_code := reg('awlad','01968688680','545466455','12345');
END;
如果要将其创建为过程
CREATE OR REPLACE PROCEDURE reg( name in varchar2,
cellNo in varchar2,
voterId in varchar2,
pass in varchar2,
succ out NUMBER )
AS
BEGIN
succ:=0;
insert into logInfo values(loginfo_seq.nextval,cellNo,pass,0);
insert into passInfo values(name,cellNo,voterId);
succ:=1;
END;
然后您需要通过传递OUT
参数
DECLARE
l_success_code NUMBER;
BEGIN
reg('awlad','01968688680','545466455','12345', l_success_code);
END;
答案 1 :(得分:3)
如果您只想做日志信息,那么使用autonomous transaction进行中间插入是合适的。
CREATE OR REPLACE FUNCTION reg(NAME IN VARCHAR2,
cellNo IN VARCHAR2,
voterId IN VARCHAR2,
pass IN VARCHAR2)
RETURN NUMBER IS
--
PROCEDURE do_loginfo (p_id NUMBER,
p_cellNo VARCHAR2,
p_pass VARCHAR2,
p_x NUMBER) IS
PRAGMA AUTONOMOUS_TRANSACTION
BEGIN
INSERT INTO logInfo VALUES (p_id, p_cellNo, p_pass, p_x);
COMMIT;
END do_loginfo;
PROCEDURE do_passInfo (p_name VARCHAR2,
p_cellNo VARCHAR2,
p_voterId VARCHAR2) IS
PRAGMA AUTONOMOUS_TRANSACTION
BEGIN
INSERT INTO passInfo VALUES (p_name, p_cellNo, p_voterId);
COMMIT;
END do_passInfo;
--
succ NUMBER;
BEGIN
succ := 0;
do_logInfo (loginfo_seq.NEXTVAL, cellNo, pass, 0);
succ := 1;
do_passInfo (NAME, cellNo, voterId);
succ := 2;
RETURN succ;
END;
请注意,它对于调试目的很有用,但由于它不是事务性的,因此不应该用它来记录数据(因为即使主事务被回滚,插入的行也会保留。)