我将问题与更复杂的查询隔离开来。这里是测试场景
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');
如果我运行查询:
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
但是,如果我只运行状态指示器
UPDATE test set value='test' RETURNING id
我得到了2行的结果:
1 2
如果我代表结果,我会有一个查询:
SELECT * FROM test WHERE id IN (1,2);
结果:
1; “测试” 2; “测试”
为什么我的初始陈述没有得到相同的结果?
答案 0 :(得分:30)
在PostgreSQL之前9.1 INSERT / UPDATE / DELETE只能用作顶级语句。这就是您收到语法错误的原因。
从9.1开始,您可以将数据修改语句与公用表表达式一起使用。您的示例查询将如下所示:
WITH updated AS (UPDATE test SET description = 'test' RETURNING id)
SELECT * FROM test WHERE id IN (SELECT id FROM updated);
从刚刚修改过的表中进行选择时要小心。你可以这样得到令人困惑的结果。因为查询是在同一个快照中执行的,SELECT不会看到UPDATE语句的效果。
答案 1 :(得分:7)
更新UPDATE
查询中的两行,添加WHERE
子句以限制受影响的行。
UPDATE test SET description = 'test' WHERE id = 1 RETURNING id
返回单行。
答案 2 :(得分:3)
您是否遗漏了IN
:... WHERE id IN (UPDATE ...
?
但是,如果我只运行状态“UPDATE test set value ='test' RETURNING id“,我得到2行的结果。为什么会这样?
您的UPDATE
没有WHERE
子句,因此它会更新每一行,其中有两行。
答案 3 :(得分:1)
您不限制您的where子句。你需要id =(blahblah)或id IN(blahblah)
答案 4 :(得分:1)
UPDATE test set description='test' RETURNING *
会为您提供初始查询所期望的结果集。
但我怀疑你是在尝试更复杂的东西?
答案 5 :(得分:0)
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;
答案 6 :(得分:-1)
我在Ants Aasma中添加,如果在同一张桌子上选择,请使用:
WITH updated AS (UPDATE test SET description = 'test' RETURNING id, description)
SELECT * FROM updated;