如何进行条件检查,返回错误或继续?

时间:2014-11-25 13:05:58

标签: postgresql

用户想要邀请朋友,但我想先进行检查。例如:

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

最好的方法是什么?

感谢。

编辑 --------------------------------------- -----------------------

以下几个小时后,我最终选择了' 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';

我认为可能存在数十种更好的方法,但这对我有用。

2 个答案:

答案 0 :(得分: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(因此您不必在以后更改应用程序代码)并在知道性能是否已经完成后将其排序是一个问题。

这里的基本思想是让数据的关系形状在任何地方都能满足任何程序检查的需要。这是关系数据建模的核心......这些日子有点像艺术遗失。

答案 1 :(得分:-1)

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

但从架构的角度来看,这是错误的。请参阅:Direct database manipulation an anti-pattern?

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

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