专业只做数据库实训和认证的品牌机构

微信公众号新浪微博
免费咨询电话:400-0909-964
当前位置: 网站首页 > postgresql > pg概述 > PostgreSQL教程 -》查询 -》WITH中的数据修改语句

PostgreSQL教程 -》查询 -》WITH中的数据修改语句

文章来源: 更新时间:2023/11/7 13:57:11

在线老师点击咨询:

最新学讯:近期OCP认证正在报名中,因考试人员较多请尽快报名获取最近考试时间,报名费用请联系在线老师,甲骨文官方认证,报名从速!

我要咨询

WITH提供了一种方式来书写在一个大型查询中使用的辅助语句。这些语句通常被称为公共表表达式或CTE,它们可以被看成是定义只在一个查询中存在的临时表。在WITH子句中的每一个辅助语句可以是一个SELECT、INSERT、UPDATE或DELETE,并且WITH子句本身也可以被附加到一个主语句,主语句也可以是SELECT、INSERT、UPDATE或DELETE。

7.8.2. WITH中的数据修改语句

你可以在WITH中使用数据修改语句(INSERT、UPDATE或DELETE)。这允许你在同一个查询中执行多个而不同操作。一个例子:

WITH moved_rows AS (

DELETE FROM products

WHERE

"date" >= '2010-10-01' AND

"date" < '2010-11-01'

RETURNING *

)

INSERT INTO products_log

SELECT * FROM moved_rows;

这个查询实际上从products把行移动到products_log。WITH中的DELETE删除来自products的指定行,以它的RETURNING子句返回它们的内容,并且接着主查询读该输出并将它插入到products_log。

上述例子中好的一点是WITH子句被附加给INSERT,而没有附加给INSERT的子SELECT。这是必需的,因为数据修改语句只允许出现在附加给顶层语句的WITH子句中。不过,普通WITH可见性规则应用,这样才可能从子SELECT中引用到WITH语句的输出。

正如上述例子所示,WITH中的数据修改语句通常具有RETURNING子句(见第 6.4 节)。它是RETURNING子句的输出,不是数据修改语句的目标表,它形成了剩余查询可以引用的临时表。如果一个WITH中的数据修改语句缺少一个RETURNING子句,则它形不成临时表并且不能在剩余的查询中被引用。但是这样一个语句将被执行。一个非特殊使用的例子:

WITH t AS (

DELETE FROM foo

)

DELETE FROM bar;

这个例子将从表foo和bar中移除所有行。被报告给客户端的受影响行的数目可能只包括从bar中移除的行。

数据修改语句中不允许递归自引用。在某些情况中可以采取引用一个递归WITH的输出来操作这个限制,例如:

WITH RECURSIVE included_parts(sub_part, part) AS (

SELECT sub_part, part FROM parts WHERE part = 'our_product'

UNION ALL

SELECT p.sub_part, p.part

FROM included_parts pr, parts p

WHERE p.part = pr.sub_part

)

DELETE FROM parts

WHERE part IN (SELECT part FROM included_parts);

这个查询将会移除一个产品的所有直接或间接子部件。

WITH中的数据修改语句只被执行一次,并且总是能结束,而不管主查询是否读取它们所有(或者任何)的输出。注意这和WITH中SELECT的规则不同:正如前一小节所述,直到主查询要求SELECT的输出时,SELECT才会被执行。

The sub-statements in WITH中的子语句被和每一个其他子语句以及主查询并发执行。因此在使用WITH中的数据修改语句时,指定更新的顺序实际是以不可预测的方式发生的。所有的语句都使用同一个snapshot执行(参见第 13 章),因此它们不能“看见”在目标表上另一个执行的效果。这减轻了行更新的实际顺序的不可预见性的影响,并且意味着RETURNING数据是在不同WITH子语句和主查询之间传达改变的唯一方法。其例子

WITH t AS (

UPDATE products SET price = price * 1.05

RETURNING *

)

SELECT * FROM products;

外层SELECT可以返回在UPDATE动作之前的原始价格,而在

WITH t AS (

UPDATE products SET price = price * 1.05

RETURNING *

)

SELECT * FROM t;

外部SELECT将返回更新过的数据。

在一个语句中试图两次更新同一行是不被支持的。只会发生一次修改,但是该办法不能很容易地(有时是不可能)可靠地预测哪一个会被执行。这也应用于删除一个已经在同一个语句中被更新过的行:只有更新被执行。因此你通常应该避免尝试在一个语句中尝试两次修改同一个行。尤其是防止书写可能影响被主语句或兄弟子语句修改的相同行。这样一个语句的效果将是不可预测的。

当前,在WITH中一个数据修改语句中被用作目标的任何表不能有条件规则、ALSO规则或INSTEAD规则,这些规则会扩展成为多个语句。

本文地址:http://www.cuug.com.cn/postgresql/pggaishu/35558624043.html 转载请注明!


在线预约 抢先报名 获取课程排期

Oracle培训机构

金牌讲师<>

冉乃纲-老师CUUG金牌讲师
冉老师 CUUG金牌讲师 Oracle及RedHat高级讲师、Unix/Linux 资深专家...[详细了解老师]

免费咨询上课流程 客服在线中

陈卫星-老师CUUG金牌讲师
陈老师 CUUG金牌讲师 精通Oracle管理、备份恢复、性能优化 11年Ora...[详细了解老师]

免费咨询上课流程 客服在线中

选学校如何选择适合自己的学校

CUUG -CHINA UNIX USER GROUP,是国际UNIX组织UNIFORUM的中国代表,是国内悠久的专业UNIX培训机构,被誉为中国UNIX 的摇篮。多年来,以提高教学质量为本,强调素质教育,积极引进、消化国外的新技术,有效的结合中国....[详情]

一站式服务(从入学到就业一帮到底)

入学

学习

就业

实操

食宿
地址:北京市海淀区北清路164号28-38号院
课程咨询:010-59426307 010-59426319 400-0909-964
企业服务:137 1818 8639(陈经理)
部分信息来源于网络,如有错误请联系指正!
版权所有@北京神脑资讯技术有限公司 (CUUG,中国UNIX用户协会) Copyright 2016 ALL Rights Reserved 京ICP备11008061号-1