DELETE
功能描述
DELETE从指定的表里删除满足WHERE子句的行。如果WHERE子句不存在,将删除表中所有行,结果只保留表结构。
注意事项
- 表的所有者、被授予表DELETE权限的用户或被授予DELETE ANY TABLE权限的用户有权删除表中数据,当三权分立开关关闭时,系统管理员默认拥有此权限。同时也必须有USING子句引用的表以及condition上读取表的SELECT权限。
- 对于多表删除语法,暂时不支持对视图进行多表删除。
- 对于子查询是STREAM计划的DELETE语句,不支持删除的行数据同时进行UPDATE更新操作。
语法格式
单表删除:
[ WITH [ RECURSIVE ] with_query [, ...] ]
DELETE [/*+ plan_hint */] [IGNORE] FROM {table_name [partition_clause] | view_name}
[ WHERE condition ]
[ ORDER BY { expression [ ASC | DESC ] } [ NULLS { FIRST | LAST } ] ]
[ LIMIT { count } ];
多表删除:
[ WITH [ RECURSIVE ] with_query [, ...] ]
DELETE [/*+ plan_hint */] [IGNORE]
FROM table_name1[ .* ] [,table_name2[ .* ]] ...
USING using_list
[ WHERE condition ];
或:
[ WITH [ RECURSIVE ] with_query [, ...] ]
DELETE [/*+ plan_hint */] [IGNORE]
table_name1[ .* ][,table_name2[ .* ]] ...
FROM using_list
[ WHERE condition ];
参数说明
- WITH [ RECURSIVE ] with_query [, ...]
用于声明一个或多个可以在主查询中通过名称引用的子查询,相当于临时表。这种子查询语句结构称为CTE(Common Table Expression)结构,应用这种结构时,执行计划中将存在CTE SCAN的内容。
如果声明了RECURSIVE,那么允许SELECT子查询通过名称引用其本身。
其中with_query的详细格式为:
with_query_name [ ( column_name [, ...] ) ] AS ( {select} )- with_query_name指定子查询生成的结果集名称,在查询中可使用该名称访问子查询的结果集。
- column_name指定子查询结果集中显示的列名。
- 每个子查询支持SELECT语句。
- RECURSIVE只能出现在WITH后面,多个CTE的情况下,只需要在第一个CTE处声明RECURSIVE。
- 使用RECURSIVE时,CTE子查询中UNION ALL和EXCEPT ALL或UNION [DISTINCT]和EXCEPT [DISTINCT]两侧的子查询结果,其数据类型必须使用cast函数转换成相同的数据类型,且两侧子查询结果的精度和字符序也要相同。如:WITH RECURSIVE cte (n) AS ( SELECT cast(id as signed int) from table_1 UNION ALL SELECT cast((n + 1) as signed int) FROM cte WHERE n < 5 ) SELECT * FROM cte。由操作符产生的类型转换具体请参见逻辑操作符规格约束、位运算操作符规格约束和算术操作符规格约束。
- plan_hint
以/*+ */的形式在DELETE关键字后,用于对DELETE对应的语句块生成的计划进行hint调优。每条语句中只有第一个/*+ plan_hint */注释块会作为hint生效,里面可以写多条hint。
- IGNORE
DELETE语句使用IGNORE关键字时,可将部分ERROR级别的错误降级为WARNING级别,并根据不同的错误场景将无效值调整为最接近的值。GaussDB支持错误降级的场景如下:
sql_mode为宽松模式的场景。
升级观察期不支持IGNORE。
- table_name
目标表的名称(可以有模式修饰)。
取值范围:已存在的表名。
- partition_clause
指定分区删除操作。
PARTITION { ( partition_name | subpartition_name [ , ...] )
关键字详见SELECT章节介绍。
- view_name
目标视图的名称。
对视图的删除,有如下约束:
- 只有直接引用基表用户列的列可进行DELETE操作。
- 视图必须至少包含一个可更新列,关于可更新列请参见CREATE VIEW。
- 不支持在顶层包含DISTINCT、GROUP BY、HAVING、LIMIT、OFFSET子句的视图。
- 不支持在顶层包含集合运算(UNION以及EXCEPT)的视图。
- 不支持目标列表中包含聚集函数、窗口函数、返回集合函数(array_agg、json_agg、generate_series等)的视图。
- 视图中支持的表类型包括普通表、临时表、全局临时表、分区表、二级分区表、ustore表、astore表。
- 连接视图只能对视图中的保留键表做删除操作,如果只存在一张保留键表,则删除该表数据,如果存在多张保留键表,仅删除FROM后的第一张保留键表的数据。关于保留键表请参见CREATE VIEW。
- 不支持对系统视图进行DELETE操作。
- 不支持多表删除功能。
- NULLS FIRST
指定空值在排序中排在非空值之前,当指定DESC排序时,本选项为默认的。
- NULLS LAST
指定空值在排序中排在非空值之后,未指定DESC排序时,本选项为默认的。
- using_list
using子句。
当删除多张目标表时,using_list指定关联表的集合时可以同时出现目标表,并且可以定义表的别名并在目标表中使用。其他情况下则目标表不可重复出现在using_list中。
设置GUC兼容性参数m_format_dev_version为's2'后,所有目标表需出现在using_list中,且两者的表名、别名、所属库名均相等时才满足匹配条件。匹配规则如下所示,如果不存在唯一匹配,语法执行失败:
- 如果目标表使用库名.表名的形式,则表名字段只能是真实表名,而非别名引用,且只能与using_list中未指定别名的对象进行匹配。
- 如果目标表未指定库名,默认属于当前正在使用的库名;
- 如果using_list中对象指定别名,按别名匹配。
- condition
一个返回Boolean值的表达式,用于判断哪些行需要被删除。不建议使用int等数值类型作为condition,因为int等数值类型可以隐式转换为bool值(非0值隐式转换为true,0转换为false),可能导致非预期的结果。
- ORDER BY
关键字详见SELECT章节介绍。
- LIMIT
关键字详见SELECT章节介绍。
示例
- 删除部分数据
--建表。 m_db=# CREATE TABLE test_t1(col1 INT,col2 INT); m_db=# INSERT INTO test_t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (4, 6); --删除表中所有记录。 m_db=# DELETE FROM test_t1 WHERE col1 = 4; --查询。 m_db=# SELECT * FROM test_t1; col1 | col2 ------+------ 1 | 1 2 | 2 3 | 3 (3 rows) - 删除所有数据
--删除所有的数据。 m_db=# DELETE FROM test_t1; --查询。 m_db=# SELECT * FROM test_t1; col1 | col2 ------+------ (0 rows) --删除表。 m_db=# DROP TABLE test_t1;
- 删除视图
--创建SCHEMA。 m_db=# CREATE SCHEMA del_view; CREATE SCHEMA m_db=# SET CURRENT_SCHEMA = 'del_view'; SET --创建表并插入数据。 m_db=# CREATE TABLE t1 (x1 int, y1 int); CREATE TABLE m_db=# CREATE TABLE t2 (x2 int PRIMARY KEY, y2 int); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t2_pkey" for table "t2" CREATE TABLE m_db=# CREATE TABLE tdata (x INT PRIMARY KEY, y INT); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "tdata_pkey" for table "tdata" CREATE TABLE m_db=# CREATE TABLE tinfo (z INT PRIMARY KEY, comm VARCHAR(20)); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "tinfo_pkey" for table "tinfo" CREATE TABLE m_db=# INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (5, 5); INSERT 0 4 m_db=# INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (5, 5); INSERT 0 4 m_db=# INSERT INTO tdata VALUES (1, 1), (2, 2), (3, 3); INSERT 0 3 m_db=# INSERT INTO tinfo VALUES (1,'one'), (2, 'two'), (3, 'three'), (5, 'wrong three'); INSERT 0 4 --创建单表视图。 m_db=# CREATE VIEW v_del1 AS SELECT * FROM t1; CREATE VIEW --通过视图删除t1中的数据。 m_db=# DELETE FROM v_del1 where y1 = 3; DELETE 1 --创建多表连接视图。 m_db=# CREATE VIEW vvt1t2 AS SELECT * FROM t1, t2 WHERE x1 = x2; CREATE VIEW m_db=# CREATE VIEW vv_dup AS SELECT td1.x x1, td1.y y1, td2.x x2, td2.y y2 FROM tdata td1, tdata td2, tinfo WHERE td2.y=tinfo.z AND td1.x=td2.y; CREATE VIEW --对多表连接的视图做删除操作。 m_db=# SELECT * FROM vvt1t2; x1 | y1 | x2 | y2 ----+----+----+---- 1 | 1 | 1 | 1 2 | 2 | 2 | 2 5 | 5 | 5 | 5 (3 rows) m_db=# DELETE FROM vvt1t2 WHERE y2 = 5; DELETE 1 m_db=# SELECT * FROM vvt1t2; x1 | y1 | x2 | y2 ----+----+----+---- 1 | 1 | 1 | 1 2 | 2 | 2 | 2 (2 rows) m_db=# SELECT * FROM vv_dup; x1 | y1 | x2 | y2 ----+----+----+---- 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 (3 rows) m_db=# DELETE FROM vv_dup WHERE y1 = 2; DELETE 1 m_db=# SELECT * FROM vv_dup; x1 | y1 | x2 | y2 ----+----+----+---- 1 | 1 | 1 | 1 3 | 3 | 3 | 3 (2 rows) --删除SCHEMA。 m_db=# DROP SCHEMA del_view; NOTICE: drop cascades to 7 other objects DETAIL: drop cascades to table t1 drop cascades to table t2 drop cascades to table tdata drop cascades to table tinfo drop cascades to view v_del1 drop cascades to view vvt1t2 drop cascades to view vv_dup DROP SCHEMA