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

nec*_*ous 3 postgresql

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

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

INSERT INTO films 
SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';
Run Code Online (Sandbox Code Playgroud)

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

INSERT INTO user_status_history(status)
UPDATE user_status SET status = 'ACTIVE' WHERE status = 'DISABLED' RETURNING status
Run Code Online (Sandbox Code Playgroud)

我可以找到的所有Postgres参考文献都建议RETURNING子句的行为与SELECT子句完全相同,但是当我运行上述代码时,我得到以下信息:

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

第2行:更新user_statuses

尽管能够执行以上查询的UPDATE部分而没有错误。

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

目标是如果可能的话,更新一个表并通过单个查询插入另一个表。

bam*_*bam 5

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

WITH updated_rows AS
(
    UPDATE products
    SET ...
    WHERE ...
    RETURNING *
)
INSERT INTO products_log
SELECT * FROM updated_rows;
Run Code Online (Sandbox Code Playgroud)

对于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;
Run Code Online (Sandbox Code Playgroud)