是否可以使用UPDATE中的RETURNING子句作为INSERT查询子句的查询子句?

时间:2010-07-08 18:52:48

标签: postgresql

我正试图在UPDATE语句中的UPDATE中使用PostgreSQL的RETURNING子句,并遇到麻烦。

Postgres允许在INSERT中使用查询子句,例如:

INSERT INTO films 
SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';

我想使用UPDATE中的RETURNING子句作为INSERT的查询子句,例如:

INSERT INTO user_status_history(status)
UPDATE user_status SET status = 'ACTIVE' WHERE status = 'DISABLED' RETURNING status

我能找到的所有Postgres引用都表明RETURNING子句的行为与SELECT子句完全相同, 但是,当我运行上述内容时,我得到以下内容:

  

错误:“UPDATE”或附近的语法错误

     

第2行:更新user_statuses

尽管能够无错误地执行上述查询的UPDATE部分。

是否可以使用UPDATE中的RETURNING子句作为INSERT查询子句的查询子句?

目标是更新一个表,并在可能的情况下使用单个查询插入另一个表。

3 个答案:

答案 0 :(得分:4)

使用PostgreSQL 9.1(或更高版本),您可以使用允许WITH clauses中的数据修改命令(INSERT / UPDATE / DELETE)的新功能,例如:

WITH updated_rows AS
(
    UPDATE products
    SET ...
    WHERE ...
    RETURNING *
)
INSERT INTO products_log
SELECT * FROM updated_rows;

使用PostgreSQL 9.0(或更低版本),您可以将UPDATE命令嵌入到一个函数中,然后从另一个执行INSERT命令的函数中使用该函数,例如:

FUNCTION update_rows()
RETURNS TABLE (id integer, descrip varchar)
AS $$
BEGIN
    RETURN QUERY
        UPDATE products
        SET ...
        WHERE ...
        RETURNING *;
END;
$$ LANGUAGE plpgsql;

FUNCTION insert_rows()
RETURNS void
AS $$
BEGIN
    INSERT INTO products_log
    SELECT * FROM update_rows() AS x;
END;
$$ LANGUAGE plpgsql;

答案 1 :(得分:1)

现在,没有。

有一个功能几乎使它成为PostgreSQL 9.0,称为Writeable CTE's,它可以完成您的想法(虽然语法不同)。

目前,您可以通过触发器或两个单独的语句来执行此操作。

答案 2 :(得分:0)

我认为这不可能像你想要做的那样。 我建议你写一个AFTER UPDATE触发器,它可以执行插入,然后。