【发布时间】:2018-09-18 15:45:03
【问题描述】:
如果我的“users”表中的用户条目的banned_till 值为nil 或小于当前时间,我希望允许用户将数据添加到我的“posts”表中。
类似(伪代码);
If (select banned_till from users where userid = $1) = nil or < currentTime
Insert in posts (col1, col2) values ('abc', 'xyz')
ELSE
RAISE Exception "User is banned"
ENDIF
目前我正在使用 2 个查询来执行此操作; 第一个检查用户是否被禁止,然后第二个插入到帖子表中。如果可以的话,我真的很想将它们组合成一个查询。
注意:我真的不希望使用和存储过程或过于特定于 SQL DB 的东西。更喜欢简单通用的东西。
编辑: 我选择了欧文答案的修改版本。
DO
$$
BEGIN
IF (select banned_till from users where unqid = 'user01') < now() THEN
RAISE EXCEPTION 'User is banned';
ELSE
insert into posts (unqid, title, link, content, author_id, author_nick, author_flair)
SELECT 'pid03', 'Sample post title', 'www.google.com', 'This is a sample Post Content', unqid, nickname, flair
from users where unqid = 'user01';
END IF;
END
$$;
优点:现在我的禁令检查发生在其他查询被触发之前。没有比赛条件。最重要的是,我现在可以收到两条不同的错误消息——一条用于禁止检查,另一条用于 unqid 不匹配。 缺点:我对用户重做了两次选择查询
【问题讨论】:
-
为什么要在 SQL 中这样做?似乎程序/应该处理这个
-
我目前正在通过应用程序代码和 2 个数据库调用来处理这个问题。但是我的应用程序中最大的时间消耗是数据库调用,如果可以的话,我想将它减少到一个。
-
那无济于事。它甚至可能使查询更长。相反,您应该着眼于优化您的查询或整个数据库。或者,如果您已经在其他地方调用 users 表(例如,当您获得用户 ID 时),您可以完全删除此查询
-
我的部分问题是数据库和应用程序位于不同的网络上,查询的网络调用是主要瓶颈。另外,我不认为插入查询真的会成为问题。我的应用非常关注读取,这就是我要优化的地方。对我来说,仅仅减少写入的数据库调用次数就足够了。
标签: sql postgresql if-statement sql-insert