sql - PostgreSQL:测试用户是否存在否则创建新用户返回他的ID

标签 sql postgresql plpgsql postgresql-9.1

我正在尝试创建一个满足以下条件的查询:

给定一个用户名和一个电子邮件地址,

  • 测试用户名或电子邮件是否已被占用,如果没有,则插入 user_account(用户名、电子邮件地址、哈希值)
  • 如果成功则返回(作为整数)新用户的user_id,如果用户名已被占用则返回-1,如果电子邮件地址已被占用则返回-2,如果两者都被占用则返回-3(或任何其他确定错误原因的方法)
  • 原子 block
  • 最优查询

到目前为止,我有以下功能:

CREATE OR REPLACE FUNCTION add_user
  (character varying(40), character varying(255), character(60))
RETURNS integer
AS $body$
DECLARE
  id record;
BEGIN
  IF EXISTS(SELECT 0 FROM user_account WHERE username = $1 AND email_address = $2)
  THEN RETURN 3;
  ELSEIF EXISTS(SELECT 0 FROM user_account WHERE username = $1)
  THEN RETURN 1;
  ELSEIF EXISTS(SELECT 0 FROM user_account WHERE email_address = $2)
  THEN RETURN 2;
  ELSE FOR id IN INSERT INTO user_account (username, email_address, hash) values ($1, $2, $3) RETURNING user_id
       LOOP
         RETURN id;
       END LOOP;
  END IF;
  RETURN 0;
END;
$body$
LANGUAGE plpgsql
VOLATILE

是否有更优雅的方式来实现这一点,而无需经历声明记录和循环的麻烦?

最佳答案

您不需要循环,只需将 INSERT ... RETURNING 的结果存储到您的变量中即可;

declare 
  id integer; -- use an integer variable
begin
    ...
    ELSE 
       INSERT INTO user_account (username, email_address, hash) values ($1, $2, $3) 
       RETURNING user_id 
       INTO id; --<< here
       return id;
    END IF;
end;

关于sql - PostgreSQL:测试用户是否存在否则创建新用户返回他的ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45970330/

相关文章:

mysql - 选择 3 个月前上次事件的地点

java - Spring Boot 和 PostgreSQL : Error creating bean with name 'entityManagerFactory' defined in class path resource

python - Django后台无限循环进程管理

postgresql - Postgres 中是否有任何已定义的函数可以让您知道什么操作会触发触发器?

postgresql - 在函数空白结果中选择语句

mysql - Slave的变化是否会出现在Master上(MySQL主从复制)

sql - 如何确认数据库是 Postgres 以及它使用 SQL 的版本?

r - 如何在 R 中中断 RPostgresql 查询

postgresql - 如何将表行传递给 plpgsql 函数?

php - 向表中添加额外的列