用于插入未按预期工作的记录的PostgreSQL函数
我试图创建一个函数,在用户不存在的情况下将用户插入记录创建到表用户中。我正在运行的PostgreSQL版本是:用于插入未按预期工作的记录的PostgreSQL函数,postgresql,plpgsql,Postgresql,Plpgsql,我试图创建一个函数,在用户不存在的情况下将用户插入记录创建到表用户中。我正在运行的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 表用户具有以下列: id serial primary key ,username text ,password_hash text 我创建了一个函数,它将返回给定
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
表用户具有以下列:
id serial primary key
,username text
,password_hash text
我创建了一个函数,它将返回给定用户名的用户ID。如果用户名不存在,则返回0,否则将返回有效的用户名。我的用户_数据模式中的此函数如下所示:
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\u user\u 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_用户内部提交
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;
这就是问题所在。在阅读文档时,函数本身似乎是一个竞争事务,提交是隐式的。谢谢你的帮助!您确实应该简化get_user_id函数,以返回COALESCESELECT distinct id FROM user_data.users,其中username=p_username,0如果您的目标是防止重复用户名,则您的函数不会在并发插入时执行此操作。确保这一点的唯一正确方法是使用唯一索引。
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;