如何在 postgresql 中将 DELETE 的返回插入到 INSERT 中?

发布于 2024-11-18 08:45:16 字数 342 浏览 3 评论 0原文

我正在尝试从一个表中删除一行并将其与一些附加数据插入到另一个表中。我知道这可以通过两个单独的命令来完成,一个用于删除,另一个用于插入新表。但是我试图将它们组合起来,但它不起作用,这是迄今为止我的查询:

insert into b (one,two,num) values delete from a where id = 1 returned one, Two, 5;

运行时出现以下错误:

错误:“删除”处或附近的语法错误

任何人都可以指出如何完成此操作,或者有更好的方法吗?或者这是不可能的?

I am trying to delete a row from one table and insert it with some additional data into another. I know this can be done in two separate commands, one to delete and another to insert into the new table. However I am trying to combine them and it is not working, this is my query so far:

insert into b (one,two,num) values delete from a where id = 1 returning one, two, 5;

When running that I get the following error:

ERROR: syntax error at or near "delete"

Can anyone point out how to accomplish this, or is there a better way? or is it not possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

多像笑话 2024-11-25 08:45:16

在 PostgreSQL 9.1 之前,您无法执行此操作,因为 PostgreSQL 9.1 尚未发布。然后语法是

WITH foo AS (DELETE FROM a WHERE id = 1 RETURNING one, two, 5)
    INSERT INTO b (one, two, num) SELECT * FROM foo;

You cannot do this before PostgreSQL 9.1, which is not yet released. And then the syntax would be

WITH foo AS (DELETE FROM a WHERE id = 1 RETURNING one, two, 5)
    INSERT INTO b (one, two, num) SELECT * FROM foo;
少跟Wǒ拽 2024-11-25 08:45:16

在 PostgreSQL 9.1 之前,您可以创建一个像这样的易失性函数(未经测试):

create function move_from_a_to_b(_id integer, _num integer)
returns void language plpgsql volatile as
$
  declare
    _one integer;
    _two integer;
  begin
    delete from a where id = _id returning one, two into strict _one, _two;
    insert into b (one,two,num) values (_one, _two, _num);
  end;
$

然后只需使用 select move_from_a_to_b(1, 5)。与两个语句相比,函数的优势在于它始终在单个事务中运行 - 无需在客户端代码中显式启动和提交事务。

Before PostgreSQL 9.1 you can create a volatile function like this (untested):

create function move_from_a_to_b(_id integer, _num integer)
returns void language plpgsql volatile as
$
  declare
    _one integer;
    _two integer;
  begin
    delete from a where id = _id returning one, two into strict _one, _two;
    insert into b (one,two,num) values (_one, _two, _num);
  end;
$

And then just use select move_from_a_to_b(1, 5). A function has the advantage over two statements that it will always run in single transaction — there's no need to explicitly start and commit transaction in client code.

归途 2024-11-25 08:45:16

对于所有版本的 PostgreSQL,您可以创建一个触发器函数来从表中删除行并将它们插入到另一个表中。但它似乎比 PostgreSQL 9.1 中发布的批量插入慢。您只需在删除旧数据之前将其移至另一个表即可。这是使用 OLD 数据类型完成的:

CREATE FUNCTION moveDeleted() RETURNS trigger AS $
    BEGIN
        INSERT INTO another_table VALUES(OLD.column1, OLD.column2,...);
        RETURN OLD;
    END;
$ LANGUAGE plpgsql;

CREATE TRIGGER moveDeleted
BEFORE DELETE ON table 
    FOR EACH ROW
        EXECUTE PROCEDURE moveDeleted();

如上面的答案,在 PostgreSQL 9.1 之后,您可以执行以下操作:

WITH tmp AS (DELETE FROM table RETURNING column1, column2, ...)
    INSERT INTO another_table (column1, column2, ...) SELECT * FROM tmp;

For all version of PostgreSQL, you can create a trigger function for deleting rows from a table and inserting them to another table. But it seems slower than bulk insert that is released in PostgreSQL 9.1. You just need to move the old data into the another table before it gets deleted. This is done with the OLD data type:

CREATE FUNCTION moveDeleted() RETURNS trigger AS $
    BEGIN
        INSERT INTO another_table VALUES(OLD.column1, OLD.column2,...);
        RETURN OLD;
    END;
$ LANGUAGE plpgsql;

CREATE TRIGGER moveDeleted
BEFORE DELETE ON table 
    FOR EACH ROW
        EXECUTE PROCEDURE moveDeleted();

As above answer, after PostgreSQL 9.1 you can do this:

WITH tmp AS (DELETE FROM table RETURNING column1, column2, ...)
    INSERT INTO another_table (column1, column2, ...) SELECT * FROM tmp;
晨与橙与城 2024-11-25 08:45:16

您的语法无效。 2 条语句是执行此操作的最佳方法。最直观的方法是先插入,然后删除。

That syntax you have there isn't valid. 2 statements is the best way to do this. The most intuitive way to do it would be to do the insert first and the delete second.

盗琴音 2024-11-25 08:45:16

作为“AI W”,两个语句无疑是您的最佳选择,但您也可以考虑为此编写一个触发器。每次在第一个表中删除某些内容时,都会填充另一个表。

As "AI W", two statements are certainly the best option for you, but you could also consider writing a trigger for that. Each time something is deleted in your first table, another is filled.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文