INSERT
注意事项
只有拥有表INSERT权限的用户,才可以向表中插入数据。用户被授予insert any table权限,相当于用户对除系统模式之外的任何模式具有USAGE权限,并且拥有这些模式下表的INSERT权限。
如果使用RETURNING子句,用户必须要有该表的SELECT权限。
如果使用ON DUPLICATE KEY UPDATE,用户必须要有该表的SELECT、UPDATE权限,唯一约束(主键或唯一索引)的SELECT权限。
如果使用query子句插入来自查询里的数据行,用户还需要拥有在查询里使用的表的SELECT权限。
生成列不能被直接写入。在INSERT命令中不能为生成列指定值,但是可以指定关键字DEFAULT。
当连接到TD兼容的数据库时,td_compatible_truncation参数设置为on时,将启用超长字符串自动截断功能,在后续的insert语句中(不包含外表的场景下),对目标表中char和varchar类型的列上插入超长字符串时,系统会自动按照目标表中相应列定义的最大长度对超长字符串进行截断。
参数说明
WITH [ RECURSIVE ] with_query [, …]
用于声明一个或多个可以在主查询中通过名称引用的子查询,相当于临时表。
如果声明了RECURSIVE,那么允许SELECT子查询通过名称引用它自己。
其中with_query的详细格式为:
– with_query_name指定子查询生成的结果集名称,在查询中可使用该名称访问子查询的结果集。
– column_name指定子查询结果集中显示的列名。
– 每个子查询可以是SELECT,VALUES,INSERT,UPDATE或DELETE语句。
– 用户可以使用MATERIALIZED / NOT MATERIALIZED对CTE进行修饰。
- 如果声明为MATERIALIZED,WITH查询将被物化,生成一个子查询结果集的拷贝,在引用处直接查询该拷贝,因此WITH子查询无法和主干SELECT语句进行联合优化(如谓词下推、等价类传递等),对于此类场景可以使用NOT MATERIALIZED进行修饰,如果WITH查询语义上可以作为子查询内联执行,则可以进行上述优化。
- 如果用户没有显示声明物化属性则遵守以下规则:如果CTE只在所属主干语句中被引用一次,且语义上支持内联执行,则会被改写为子查询内联执行,否则以CTE Scan的方式物化执行。
说明:
INSERT ON DUPLICATE KEY UPDATE不支持WITH及WITH RECURSIVE子句。
plan_hint子句
table_name
要插入数据的目标表名。
取值范围:已存在的表名。
column_name
目标表中的字段名:
- 字段名可以有子字段名或者数组下标修饰。
- 没有在字段列表中出现的每个字段,将由系统默认值,或者声明时的默认值填充,若都没有则用NULL填充。例如,向一个复合类型中的某些字段插入数据的话,其他字段将是NULL。
- 目标字段(column_name)可以按顺序排列。如果没有列出任何字段,则默认全部字段,且顺序为表声明时的顺序。
- 如果value子句和query中只提供了N个字段,则目标字段为前N个字段。
- value子句和query提供的值在表中从左到右关联到对应列。
取值范围:已存在的字段名。
expression
赋予对应column的一个有效表达式或值:
- 当数据库的兼容性为 B 时,VALUES 后面的表达式中允许引用字段名。VALUES 与 ON DUPLICATE KEY UPDATE 后的表达式的计算规则如下:
- 表达式的计算顺序按照 SQL 语句的字段书写顺序进行执行。
- 当引用的字段未执行计算或正在计算(引用自身):
- 所引用的字段的默认值为常量或存在旧元组,则取默认值或旧元组值参与当前表达式的计算。
- 所引用的字段的默认值不是常量(是方法、表达式等)且不存在旧元组值和not null约束时,取null参与当前表达式的计算。
- 所引用的字段包含not null约束时,则取引用字段的基础值参与计算,若无基础值则继续使用null。
- 当引用的字段已执行计算,取该字段的当前记录的值参与当前表达式的计算。
其余与其他兼容性的数据库表现相同。
其他数据库兼容性模式的语法说明如下:
如果是INSERT ON DUPLICATE KEY UPDATE语句下,expression可以为VALUES(column_name)或EXCLUDED.column_name用来表示引用冲突行对应的column_name字段的值。需注意,其中VALUES(column_name)不支持嵌套在表达式中(例如VALUES(column_name)+1),但EXCLUDED不受此限制。
向表中字段插入单引号 “ ‘ “时需要使用单引号自身进行转义。
- 当数据库的兼容性为 B 时,VALUES 后面的表达式中允许引用字段名。VALUES 与 ON DUPLICATE KEY UPDATE 后的表达式的计算规则如下:
DEFAULT
对应字段名的缺省值。如果没有缺省值,则为NULL。
-
一个查询语句(SELECT语句),将查询结果作为插入的数据。
RETURNING
返回实际插入的行,RETURNING列表的语法与SELECT的输出列表一致。注意:INSERT ON DUPLICATE KEY UPDATE不支持RETURNING子句。
output_expression
INSERT命令在每一行都被插入之后用于计算输出结果的表达式。
取值范围:该表达式可以使用table的任意字段。可以使用*返回被插入行的所有字段。
output_name
字段的输出名称。
取值范围:字符串,符合标识符命名规范。
ON DUPLICATE KEY UPDATE
对于带有唯一约束(UNIQUE INDEX或PRIMARY KEY)的表,如果插入数据违反唯一约束,则对冲突行执行UPDATE子句完成更新,对于不带唯一约束的表,则仅执行插入。UPDATE时,若指定NOTHING则忽略此条插入,可通过”EXCLUDE.” 或者 “VALUES()” 来选择源数据相应的列。
支持触发器,触发器执行顺序由实际执行流程决定:
- 执行insert: 触发 before insert、 after insert触发器。
- 执行update:触发before insert、before update、after update触发器。
- 执行update nothing: 触发before insert触发器。
不支持延迟生效(DEFERRABLE)的唯一约束或主键。
如果表中存在多个唯一约束,如果所插入数据违反多个唯一约束,对于检测到冲突的第一行进行更新,其他冲突行不更新(检查顺序与索引维护具有强相关性,一般先创建的索引先进行冲突检查)。
如果插入多行,这些行均与表中同一行数据存在唯一约束冲突,则按照顺序,第一条执行插入或更新,之后依次执行更新。
主键、唯一索引列不允许UPDATE。
不支持列存,不支持外表、内存表。
expression支持使用子查询表达式,其语法与功能同UPDATE。子查询表达式中支持使用“EXCLUDED.”来选择源数据相应的列。
- 右值引用示例(兼容B模式下):