简体   繁体   English

使用WITH子句即时更新创建的记录

[英]Instantly update created record with a WITH clause

I'm trying to update a record, created with WITH clause in the same query, like so: 我正在尝试更新在同一查询中使用WITH子句创建的记录,如下所示:

WITH
  document AS (
    INSERT INTO documents (name) VALUES ($1)
    RETURNING *
  )
UPDATE documents
SET documents.description = $2
FROM document
WHERE documents.id = document.id;

I've also tried 我也试过了

WITH
  new_document AS (
    INSERT INTO documents (name) VALUES ($1)
    RETURNING *
  ),
  updated_document AS (
    UPDATE documents
    SET documents.description = $2
    WHERE documents.id = (SELECT id FROM new_document)
    RETURNING *
  )
SELECT * FROM updated_document;

But it doesn't seem to work. 但它似乎没有用。 I know this example is silly since I can simply create a new document with both name and description at the same time, but I need it to do it this way in my app; 我知道这个例子很傻,因为我可以同时创建一个同时包含名称和描述的新文档,但我需要它在我的应用程序中这样做; the example is simplified on purpose. 这个例子是故意简化的。

Edit 编辑

I've created a Gist with a real world example. 我用真实世界的例子创造了一个要点 I know I can embed the logic of updating document_id into the function body. 我知道我可以将更新document_id的逻辑嵌入到函数体中。 I guess. 我猜。 But imagine that urls can correspond not only to documents, but to many other entities, like, documents, stories, users, articles, tags, etc., etc., embedding references to all these entities into the function body is tedious, since (due to function overloading) I would have to create functions like get_url_for_document(id uuid) , get_url_for_story(id uuid) , get_url_for_user(id uuid) , etc., etc. 但是想象一下, urls不仅可以对应于文档,还可以对应于许多其他实体,例如文档,故事,用户,文章,标签等等,将所有这些实体的引用嵌入到函数体中是很乏味的,因为(由于函数重载)我必须创建函数,如get_url_for_document(id uuid)get_url_for_story(id uuid)get_url_for_user(id uuid)等等。

Do it in two separate statements or inside a function. 在两个单独的语句中或在函数内部执行。 You cannot do it like you tried due to the way how WITH is implemented. 由于实现WITH的方式,你不能像你尝试的那样去做。

From documentation : 来自文档

The sub-statements in WITH are executed concurrently with each other and with the main query. WITH中的子语句彼此同时并与主查询一起执行。 Therefore, when using data-modifying statements in WITH, the order in which the specified updates actually happen is unpredictable. 因此,在WITH中使用数据修改语句时,指定更新实际发生的顺序是不可预测的。 All the statements are executed with the same snapshot (see Chapter 13), so they cannot "see" one another's effects on the target tables. 所有语句都使用相同的快照执行(参见第13章),因此它们无法“看到”彼此对目标表的影响。

What you are attempting to do is impossible. 你试图做的事是不可能的。

From the manual: https://www.postgresql.org/docs/current/static/queries-with.html 从手册: https//www.postgresql.org/docs/current/static/queries-with.html

WITH t AS (
    UPDATE products SET price = price * 1.05
    RETURNING *
)
SELECT * FROM products;

the outer SELECT would return the original prices before the action of the UPDATE, while in 外部SELECT将在UPDATE的操作之前返回原始价格,而在

WITH t AS (
    UPDATE products SET price = price * 1.05
    RETURNING *
)
SELECT * FROM t;

the outer SELECT would return the updated data. 外部SELECT将返回更新的数据。


In your given example your update trying to act on rows which don't exist. 在您给出的示例中,您的更新尝试对不存在的行执行操作。 This is not fixable using a WITH clause. 使用WITH子句无法修复此问题。

I would be interested to understand why your code has forced you to do it this way. 我很想知道为什么你的代码强迫你这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 mysql 的 group by 子句中最后创建 select 记录? - How to select last created record in a group by clause in mysql? 检查记录是否(立即)存在于MVC中 - Check record if exist (instantly) in MVC 是否可以更新与where子句中使用的字段相同的记录中的字段 - Is it possible to update a field in a record which is the same field used in the where clause 使用触发器更新SQL中的记录时,在FileMaker中添加记录时,不能将OUTPUT子句与INTO子句一起使用 - Cannot use OUTPUT clause with INTO clause when using Triggers to update records in SQL, when adding a record in FileMaker 根据下一个创建的记录创建日期,更新为空的end_dt列 - update a end_dt column which is null based on next created record created date Orientdb where子句不返回记录 - Orientdb where clause not returning the record 如何更新给定一周(星期日至星期六)内创建的最新记录以外的所有记录? - How to update all but the latest record created within a given week (sun - sat)? Sql Query IN子句限制1记录 - Sql Query IN clause limit 1 Record (1093, u“您不能在 FROM 子句中指定目标表 'wallet_consume_record' 进行更新”) 在 mysql 中使用删除时 - (1093, u“You can't specify target table 'wallet_consume_record' for update in FROM clause”) when using delete in mysql 用户在Where子句中创建的功能 - user created Functions in Where clause
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM