[英]Oracle 12c SQL Function call not working as desired
我在SQL中有一个将用户插入USERS的函数。 当我使用SELECT insert_users('user', 'email', 'hash') FROM dual;
Oracle 12c应用程序中的函数时SELECT insert_users('user', 'email', 'hash') FROM dual;
它运行,但从异常返回FAIL
。 运行此SQL语句时,在SQL Developer中也会发生相同的事情,但是,当我直接在SQL Developer中运行或调试该函数时,它将成功执行。 因此,我认为问题出在SQL语句中。 那么,需要进行哪些更改才能使其正常工作?
SQL函数
create or replace FUNCTION insert_users(p_user_name in varchar2,
p_user_email in varchar2, p_user_password in varchar2)
RETURN VARCHAR2 AS
p_salt varchar2(20) := '';
BEGIN
select dbms_random.string('P', 20) str
into p_salt
from dual;
INSERT INTO USERS(USER_ID, USER_NAME, USER_EMAIL, SALT, USER_PASSWORD)
VALUES (seq_users.nextval, p_user_name, p_user_email, p_salt, p_user_password);
return 'SUCCESS';
EXCEPTION
WHEN others THEN
RETURN 'FAIL';
END;
SQL调用
SELECT insert_users('user', 'email', 'hash') FROM dual;
PL / SQL块(直接从运行功能中获取)
DECLARE
P_USER_NAME VARCHAR2(200);
P_USER_EMAIL VARCHAR2(200);
P_USER_PASSWORD VARCHAR2(200);
v_Return VARCHAR2(200);
BEGIN
P_USER_NAME := 'user';
P_USER_EMAIL := 'email';
P_USER_PASSWORD := 'hash';
v_Return := USER.INSERT_USERS(
P_USER_NAME => P_USER_NAME,
P_USER_EMAIL => P_USER_EMAIL,
P_USER_PASSWORD => P_USER_PASSWORD
);
:v_Return := v_Return;
--rollback;
END;
如果您没有挤压异常,则会看到:
ORA-14551:无法在查询中执行DML操作
您的函数正在执行DML-即插入表中。 从PL / SQL上下文运行时可以,尽管通常认为最好还是使用过程来完成。 但是由于您的函数正在执行此操作,因此您不能在查询中调用它。
捕获和压榨错误通常被认为是一个错误 。 您正在做的所有事情都在隐藏有用的信息。 调用者不知道为什么函数调用失败,并且任何调查问题的人都不知道发生了什么。
更好的方法是只执行一个过程。 如果插入有效,那很好。 如果发生任何类型的错误,请传播异常,客户端或调用方将看到该错误并知道实际出了什么问题。 您不能从查询中调用该过程,但可以从匿名块中调用,也可以从SQL * Plus和SQL Developer在匿名块周围execute
包装器中调用它。
create or replace PROCEDURE insert_users(p_user_name in varchar2,
p_user_email in varchar2, p_user_password in varchar2) AS
BEGIN
INSERT INTO USERS(USER_ID, USER_NAME, USER_EMAIL, SALT, USER_PASSWORD)
VALUES (seq_users.nextval, p_user_name, p_user_email, dbms_random.string('P', 20), p_user_password);
END;
/
Procedure INSERT_USERS compiled
EXEC insert_users('user', 'email', 'hash');
PL/SQL procedure successfully completed.
select * from users;
USER_ID USER_NAME USER_EMAIL SALT USER_PASSWORD
---------- -------------------- -------------------- -------------------- ----------------------------------------------------------------
1 user email Er-U1zL-v0lP%1m*Tz&t hash
您实际上并不需要p_salt
变量,可以将dbms_random
作为插入的一部分来调用,因此我已将其删除。
您可能想在存储密码之前先使用Salt对密码进行哈希处理...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.