postgresql - 用于插入记录的 PostgreSQL 函数未按预期工作
问题描述
如果用户不存在,我正在尝试创建一个函数来创建用户(将记录插入表 USERS)。我正在运行的 PostgreSQL 版本是:
PostgreSQL 9.2.24 on x86_64-redhat-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28), 64-bit
表 USERS 具有以下列:
id serial primary key
,username text
,password_hash text
我创建了一个函数,它将返回给定用户名的用户 ID。如果用户名不存在,则返回 0,否则将返回有效的用户 ID。这个函数(在我的 USER_DATA 模式中)如下:
CREATE OR REPLACE FUNCTION user_data.get_user_id(
p_username text)
RETURNS integer
LANGUAGE 'plpgsql'
COST 100
VOLATILE
AS $BODY$
DECLARE user_id int;
BEGIN
IF exists(select distinct id from user_data.users where username = p_username) THEN
SELECT distinct id INTO user_id
FROM user_data.users
WHERE username = p_username;
ELSE
user_id = 0;
END IF;
RETURN user_id;
END;
$BODY$;
如果 GET_USER_ID 返回 0,我现在正在研究一个创建用户的函数。三个可能的返回值是:
TRUE - if user is created
FALSE - if username already exists and user is not created
ERROR - if there is any type of error
测试此功能时,这些是我的结果:
当用户已经存在时运行:FALSE <--这是预期的
在用户不存在时运行:错误 <-- 这不是预期的。
任何人都可以提供有关为什么我可能会在以下逻辑中出现错误的见解:
CREATE OR REPLACE FUNCTION user_data.create_user(in p_username text, p_password_hash text)
returns text AS $$
DECLARE
v_user_created text;
v_user_id int;
v_error text;
BEGIN
select user_data.get_user_id(p_username) into v_user_id;
IF v_user_id = 0 THEN
insert into user_data.users(username, password_hash) values (p_username, p_password_hash);
commit;
v_user_created := 'TRUE';
ELSE
v_user_created := 'FALSE';
END IF;
RETURN v_user_created;
EXCEPTION WHEN OTHERS THEN
BEGIN
v_error := 'ERROR';
RETURN v_error;
END;
END;
$$ LANGUAGE plpgsql;
select user_data.create_user('new_user', 'sample_password_not_hashed');
非常感谢任何帮助、见解或批评。
解决方案
COMMIT
里面create_user
不是必须的。
IF v_user_id = 0 THEN
insert into users(username, password_hash) values (p_username, p_password_hash);
--commit;
v_user_created := 'TRUE';
ELSE
v_user_created := 'FALSE';
END IF;
推荐阅读
- google-apps-script - 为什么 addRange 函数在 Google Apps 脚本中不起作用?
- python - 如何从内部装饰器类访问类的实例?
- c# - 不同的 DLL 版本,一个代码库
- firebase - 如何防止实时数据库firebase中仅节点或某些键的读取访问?
- ios - Alamofire 在 HTTPS 上变慢但在 HTTP 上很好
- gatling - 如何在 Gatling 中执行场景时只加载一次 gatling 配置?
- image - Pass/Fail images in Tkinter
- php - 对 laravel csrf 令牌不匹配错误做出反应,即使在尝试了很多之后也不起作用
- node.js - 在 Heroku 问题上部署平均堆栈应用程序
- firefox - 如何将 URL 添加到给定的手写笔插件样式?