无法从postgres中的UPDATE RETURNING子句中选择

时间:2011-08-25 14:13:49

标签: sql postgresql

我将问题与更复杂的查询隔离开来。这里是测试场景

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; “测试”

为什么我的初始陈述没有得到相同的结果?

7 个答案:

答案 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;