2017-05-03 90 views
0

如果我有条件插入作为事务的一部分。在事务中,我需要插入一些不相关的数据,但是如果条件插入实际上不影响任何行,我想放弃这个。PostgreSQL - 在条件插入后中止

INSERT INTO TicketBookings(BookingId, ConcertId, NumSeats) SELECT 1, 1, 5 WHERE (SELECT AvailSeats FROM Concerts WHERE ConcertId = 1) >= 5; 

不管这是否插入行或没有(也不会,如果5个席位不可用),它仍然是一个“成功”的查询。进一步在事务是一个INSERT的一些不相关的数据,所以(据我所知)我不能使用触发器或外键,因为它不会传递我需要的无关数据。

我想要做的是让受我的条件插入的行数和中止/回滚事务,如果是0

有什么办法?

由于:-)

+0

需要PLPGSQL筹集例外,我相信,除非。 –

+0

您可以使用检查约束'availableseats> = 0'作为列定义。 (并在两个表事务中更新) – wildplasser

+0

是的,Postgres会向客户端报告受影响的行数,以响应'INSERT'。您如何访问此信息取决于您使用哪个客户端库运行查询。在'libpq'中,你可以从['PQcmdTuples()'](https://www.postgresql.org/docs/current/static/libpq-exec.html#LIBPQ-PQCMDTUPLES)中获得它。查看您的客户端库的文档,了解他们如何公开它。 (如果你调用的'execute()'函数返回一个整数,那可能就是这样。) –

回答

0

的一个解决方案时,没有行插入,被零除触发异常。

一个行插入,OK

BEGIN 
Time: 0.087 ms 
t=# with i as (insert into s100 (rec_time) select 0 where true returning 1 as c) select 2/count(1) from i; 
?column? 
---------- 
     2 
(1 row) 

Time: 0.266 ms 
t=# end; 
COMMIT 
Time: 1.651 ms 

零行会中止交易:

BEGIN 
Time: 0.082 ms 
t=# with i as (insert into s100 (rec_time) select 0 where false returning 1 as c) select 2/count(1) from i; 
ERROR: division by zero 
Time: 0.276 ms 
t=# end; 
ROLLBACK 
Time: 0.178 ms