Cannot SELECT from UPDATE RETURNING clause in postgres
我将问题与更复杂的查询隔离开来。 这里是测试场景
1 2 3 4 5 6 7 8 | DROP TABLE test; CREATE TABLE test ( id INTEGER, description VARCHAR(100) ); INSERT INTO test(id, description) VALUES (1,'new'); INSERT INTO test(id, description) VALUES (2,'new'); |
如果我运行查询:
1 | SELECT * FROM test WHERE id IN (UPDATE test SET description='test' RETURNING id) |
我收到以下错误:
错误:"test"或其附近的语法错误
第1行:SELECT * FROM测试WHERE id(UPDATE测试集描述='测试'RE ...
^
*** Fehler ***
错误:"test"或其附近的语法错误
SQL状态:42601
贼臣:37
但是,如果我只运行国家政府
1 | UPDATE test SET VALUE='test' RETURNING id |
我得到一个2行的结果:
1
2
如果我代表结果,我会有一个查询,如:
1 | SELECT * FROM test WHERE id IN (1,2); |
结果:
1;"测试"
2;"测试"
为什么我的初始陈述没有得到相同的结果?
在PostgreSQL 9.1 INSERT / UPDATE / DELETE之前只能用作顶级语句。这就是您收到语法错误的原因。
从9.1开始,您可以将数据修改语句与公用表表达式一起使用。您的示例查询将如下所示:
1 2 | WITH updated AS (UPDATE test SET description = 'test' RETURNING id) SELECT * FROM test WHERE id IN (SELECT id FROM updated); |
从刚刚修改过的表中进行选择时要小心。你可以这样得到令人困惑的结果。因为查询是在同一个快照中执行的,SELECT不会看到UPDATE语句的效果。
您在
1 | UPDATE test SET description = 'test' WHERE id = 1 RETURNING id |
返回单行。
你错过了
However if I only run the statemennt"UPDATE test set value='test'
RETURNING id", I get a result with 2 rows. Why is that?
您的
1 | UPDATE test SET description='test' RETURNING * |
会给你初始查询所期望的结果集。
但我怀疑你在尝试更复杂的东西?
你不是限制你的where子句。你需要id =(blahblah)或id IN(blahblah)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | DROP TABLE IF EXISTS test_tab; CREATE TABLE test_tab ( id INTEGER, description VARCHAR(100) ); INSERT INTO test_tab(id, description) VALUES (1,'new'); INSERT INTO test_tab(id, description) VALUES (2,'new'); SELECT * FROM test_tab; DO $$ DECLARE myID test_tab.id%TYPE; testID test_tab.id%TYPE; cur_IDs CURSOR FOR SELECT id FROM test_tab; BEGIN OPEN cur_IDs; LOOP FETCH cur_IDs INTO testID; EXIT WHEN testID IS NULL; UPDATE test_tab SET description='test' WHERE id = testID RETURNING id INTO myID; raise notice 'myID %', myID; END LOOP; CLOSE cur_IDs; END$$; DROP TABLE IF EXISTS test_tab; |
我是从Ants Aasma中添加的,如果在同一张桌子上选择,使用:
1 2 | WITH updated AS (UPDATE test SET description = 'test' RETURNING id, description) SELECT * FROM updated; |