postgres 中的条件 INSERT INTO 语句
Posted
技术标签:
【中文标题】postgres 中的条件 INSERT INTO 语句【英文标题】:Conditional INSERT INTO statement in postgres 【发布时间】:2013-03-20 13:30:34 【问题描述】:我正在为模拟航空公司预订数据库编写预订程序,我真正想做的是这样的:
IF EXISTS (SELECT * FROM LeadCustomer
WHERE FirstName = 'John' AND Surname = 'Smith')
THEN
INSERT INTO LeadCustomer (Firstname, Surname, BillingAddress, email)
VALUES ('John', 'Smith', '6 Brewery close,
Buxton, Norfolk', 'cmp.testing@example.com');
但是 Postgres 不支持 IF
不加载 PL/pgSQL 扩展的语句。我想知道是否有办法做到这一点,或者在这一步中是否需要进行一些用户交互?
【问题讨论】:
为什么不直接加载 PL/pgSQL 扩展呢? @MattBall:在实验室计算机上安装 postgres。使用该扩展不在规范中。 【参考方案1】:该特定命令可以这样完成:
insert into LeadCustomer (Firstname, Surname, BillingAddress, email)
select
'John', 'Smith',
'6 Brewery close, Buxton, Norfolk', 'cmp.testing@example.com'
where not exists (
select 1 from leadcustomer where firstname = 'John' and surname = 'Smith'
);
它将插入选择语句的结果,select
只会在该客户不存在时返回一行。
【讨论】:
我认为这里有一场(非常小的)比赛? select子查询运行,返回0行,另一个线程发生insert,然后发生LeadCustomer insert? @Kevin 将引发主键异常,应用程序将决定做什么。 我很困惑,这个问题在任何地方都没有提到主键。如果 (firstname, surname) 上有一个主键,为什么不先尝试插入? @Kevin 我会先尝试插入。问题只是关于语法。 有没有办法像这样插入多行?【参考方案2】:自 9.5 版本起包含 pgsql upsert,使用 INSERT ... ON CONFLICT DO UPDATE ...
下面的答案不再相关。几年后发布了 Postgres 9.5,并提供了更好的解决方案。
如果不添加新功能,Postgres 没有“upsert”功能。 您需要做的是运行选择查询并查看是否有匹配的行。如果你这样做,然后插入它。
我知道你并不完全想要一个 upsert,但它几乎是一样的。
【讨论】:
即使发生冲突(尝试插入时),这也会继续增加自动递增的 id “检查结果,有条件地插入”容易出现竞争条件:如果你有两个线程同时在做,你可以得到两个插入。 @CharlesDuffy 不在事务中(如果选择更新,则不在事务中)以上是关于postgres 中的条件 INSERT INTO 语句的主要内容,如果未能解决你的问题,请参考以下文章
MySQL中的insert ignore into, replace into等的一些用法小结(转)
有条件的 INSERT INTO MySQL - 不存在的地方
Oracle中如何用一条insert into 语句插入多条数据 如: insert into 表 values(多条数据)????????