2014-11-25 64 views
1

用户想邀请朋友,但我想先做一个检查。例如:如何进行有条件检查,返回错误或继续?

SELECT friends_email from invites where friends_email = $1 limit 1; 

如果找到一个,然后我要回的消息,如“已经邀请了这位朋友。”

如果没有找到一个,然后我希望做一个插入

INSERT INTO invites etc... 

但后来我需要返回主用户的REGION_ID

SELECT region_id from users where user_id = $2 

什么是做到这一点的最好方法是什么?

谢谢。

EDIT ------------------------------------------- -------------------

经过几个小时之后,我才在'plpgsql'结束了。

IF EXISTS (SELECT * FROM invitations WHERE email = friends_email) THEN 
    return 'Already Invited'; 
END IF; 

INSERT INTO invitations (email) VALUES (friends_email); 

return 'Invited'; 

我不确定有可能有几十种更好的方法,但这对我有用。

+0

您是否知道SQL中的CASE WHEN ... THEN ... ELSE ... END? – 2014-11-25 13:22:19

+0

@MladenUzelac如果插入if-not-exists会有什么好处? – 2014-11-25 13:34:25

+0

看来你需要为它编写pl/pgsql函数或者在你的应用程序中解决它。 – 2014-11-25 14:15:01

回答

1

无需编写确切的代码片段你...

考虑解决这个问题的塑造你的数据以符合您的业务规则。如果您只能邀请一个人,那么您应该有一个“邀请”表,通过任意列定义唯一邀请的UNIQUE规则来反映此情况。如果它只是一个电子邮件地址,则将“invites.email”声明为唯一列。

然后做一个INSERT。编写插页,以便利用Postgres' RETURNING clause为成功提供答案。如果INSERT失败(因为您已经拥有该电子邮件地址 - 这是您希望执行的检查的重点),那么在应用程序代码中捕获失败并返回相应的响应。

伪代码:

应用:

try 
    invite.insert(NewGuy) 
catch error.UniqueFail 
    return "He's already been invited" 
# ...do other stuff 

Postgres的:

INSERT INTO invites 
    (data fields + SELECT region thingy) 
    VALUES 
    (some arrangement of data that includes "region_id") 
    RETURNING region_id 

如果这是很难发挥作用的第一次尝试,措辞插入目标的CTE可能很有帮助。如果一切都失败了,暂时将它写在plpgsql中,确保外部接口接受一个正常的INSERT(所以你不必在以后更改应用程序代码),并在知道性能是否为问题。

这里的基本思想是让数据的关系形状在任何可能的情况下都不需要任何程序检查。这是关系数据建模的核心......现在有些失落的艺术。

+0

zxq9,感谢您的留言。当我通过不同的排列组合时,我一直回到它。我开始使用常规的SQL,然后以'plpgsql'结尾,最后以最简单的方式添加到原始文章中。尽管我刚开始返回region_id,但最终发现我并不需要它。但整件事情都是一次很好的学习经历。再次感谢。 – user390480 2014-11-27 01:26:56

+0

@ user390480好听!我特别高兴你在这个过程中学到了很多东西。这是迄今为止最好的结果。 – zxq9 2014-11-27 01:29:12

-1

您可以创建SQL存储过程来实现上述功能。

但是这是错误的形式体系结构的观点。请参阅:Direct database manipulation an anti-pattern?

DB有责任范围:存储数据。

您必须将业务逻辑放入业务层。