使用Postgres WITH语句

时间:2015-07-04 22:31:13

标签: sql postgresql

WITH values (a_name, a_area ) AS ( VALUES ('thename', 'thearea')),
  t AS (SELECT name FROM area_table, values WHERE name=a_name),
  i AS (INSERT INTO area_table (name, area) 
           SELECT a_name, a_area FROM values WHERE a_name NOT IN (SELECT name FROM t))  
SELECT a_name,a_area FROM values WHERE a_name IN (SELECT name FROM t);

以上查询运行正常。我只是想知道它是否会出现并发问题,如果数据被两个或多个人同时插入它可能有任何问题或者它没问题?请帮助我对Postgres CTE和WITH声明不太了解。

1 个答案:

答案 0 :(得分:0)

  

如果两个或多个人同时插入数据[可能]有任何问题[?]

是的,会有问题。在并发执行的情况下,该语句是不安全的,因为它可以引发唯一的违规错误(如果存在合适的唯一约束)或插入重复项(如果不存在唯一约束)。

这个片段:

NOT IN (SELECT name FROM t)

可以在多个会话中同时运行 。这两个会话都没有INSERT编辑元组。即使它有,它也是未提交的,因此SELECT不会在其快照中看到它。两个实例都将返回false,从而执行INSERT

(另外,如果列可以为空,NOT IN可能会产生意外结果,并且速度很慢。请使用NOT EXISTS或左反连接。

在一个语句中执行所有操作 - wCTE或其他 - 不会使并发问题消失,尽管它可能会使它更难以触发它们。即使是两个简单的UPDATE也可以进行与其并发执行相关的交互(以死锁的形式)。认为ACID的“atomacity”意味着某种语句在逻辑瞬间执行是一个常见的错误。事实并非如此。原子性属性是指一个事务要么所有更改生效,要么回滚而没有更改生效。

请参阅:How to UPSERT (MERGE, INSERT ... ON DUPLICATE UPDATE) in PostgreSQL?