INSERT
功能描述
向表中插入一行或多行数据。
注意事项
- 只有拥有表INSERT权限的用户,才可以向表中插入数据。用户被授予insert any table权限,相当于用户对除系统模式之外的任何模式具有USAGE权限,并且拥有这些模式下表的INSERT权限。
- 如果使用RETURNING子句,用户必须要有该表的SELECT权限。
- 如果使用ON DUPLICATE KEY UPDATE,用户必须要有该表的INSERT、UPDATE权限,UPDATE子句中列的SELECT权限。
- 如果使用query子句插入来自查询里的数据行,用户还需要拥有在查询里使用的表的SELECT权限。
- 生成列不能被直接写入。在INSERT命令中不能为生成列指定值,但是可以指定关键字DEFAULT。
语法格式
INSERT [/*+ plan_hint */] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[(col_name [, col_name] ...)]
{VALUES | VALUE} (value_list) [, (value_list)] ...
[ON DUPLICATE KEY UPDATE column_name = {expression | DEFAULT}[, ...]]
[ RETURNING {* | {output_expression [ [ AS ] output_name ] }[, ...]} ];
INSERT [/*+ plan_hint */] [IGNORE] [INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
SET column_name = {expression | DEFAULT}[, ...]
[ON DUPLICATE KEY UPDATE column_name = {expression | DEFAULT}[, ...]]
[ RETURNING {* | {output_expression [ [ AS ] output_name ] }[, ...]} ];
INSERT [/*+ plan_hint */] [IGNORE] [INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[(col_name [, col_name] ...)]
query
[ON DUPLICATE KEY UPDATE column_name = {expression | DEFAULT}[, ...]]
[ RETURNING {* | {output_expression [ [ AS ] output_name ] }[, ...]} ];
INSERT [/*+ plan_hint */] [IGNORE] [INTO] view_name
[(col_name [, col_name] ...)]
{VALUES | VALUE} (value_list) [, (value_list), ...]
[ RETURNING {* | {output_expression [ [ AS ] output_name ] }[, ...]} ];
INSERT [/*+ plan_hint */] [IGNORE] [INTO] view_name
SET column_name = {expression | DEFAULT}[, ...]
[ RETURNING {* | {output_expression [ [ AS ] output_name ] }[, ...]} ];
INSERT [/*+ plan_hint */] [IGNORE] [INTO] view_name
[(col_name [, col_name] ...)]
query
[ RETURNING {* | {output_expression [ [ AS ] output_name ] }[, ...]} ];
参数说明
- plan_hint子句
以/*+ */的形式在INSERT关键字后,用于对INSERT对应的语句块生成的计划进行hint调优。每条语句中只有第一个/*+ plan_hint */注释块会作为hint生效,里面可以写多条hint。
- IGNORE
INSERT语句使用IGNORE关键字时,可将部分ERROR级别的错误降级为WARNING级别,并根据不同的错误场景将无效值调整为最接近的值。GaussDB支持错误降级的场景如下:
- 破坏NOT NULL约束。
- 唯一键冲突。
- 插入的值无法匹配对应的分区。
- 指定分区插入时,插入的数据与指定分区不匹配。
- 子查询返回多行。
- sql_mode为宽松模式的场景。
- table_name
要插入数据的目标表名。
取值范围:已存在的表名。
- partition_name
分区名。
- column_name
目标表中的字段名称:
- 字段名可以有子字段名或者数组下标修饰。
- 没有在字段列表中出现的每个字段,将由系统默认值,或者声明时的默认值填充,若都没有则用NULL填充。例如,向一个复合类型中的某些字段插入数据的话,其他字段将是NULL。
- 目标字段(column_name)可以按顺序排列。如果没有列出任何字段,则默认全部字段,且顺序为表声明时的顺序。
- 如果value子句和query中只提供了N个字段,则目标字段为前N个字段。
- value子句和query提供的值在表中从左到右关联到对应列。
取值范围:已存在的字段名。
- expression
赋予对应column的一个有效表达式或值:
- 如果是在INSERT ON DUPLICATE KEY UPDATE语句下,expression可以为VALUES(column_name),用来表示引用冲突行对应的column_name字段的值。其中VALUES(column_name)支持嵌套在复合表达式中,例如:VALUES(column_name) +1、VALUES(column_name) + VALUES(column_name)、function_name(VALUES(column_name))等。
上述VALUES(column_name)特性仅支持在ON DUPLICATE KEY UPDATE子句中使用。
- 向表中字段插入单引号 " ' "时需要使用单引号自身进行转义。
- 如果插入行的表达式不是正确的数据类型,系统试图进行类型转换,若转换不成功,则插入数据失败,系统返回错误信息。
- 如果是在INSERT ON DUPLICATE KEY UPDATE语句下,expression可以为VALUES(column_name),用来表示引用冲突行对应的column_name字段的值。其中VALUES(column_name)支持嵌套在复合表达式中,例如:VALUES(column_name) +1、VALUES(column_name) + VALUES(column_name)、function_name(VALUES(column_name))等。
- DEFAULT
对应字段名的缺省值。如果没有缺省值,则为NULL。
- query
一个查询语句(SELECT语句),将查询结果作为插入的数据。
- RETURNING
返回实际插入的行,RETURNING列表的语法与SELECT的输出列表一致。
- ON DUPLICATE KEY UPDATE
对于带有唯一约束(UNIQUE INDEX或PRIMARY KEY)的表,如果插入数据违反唯一约束,则对冲突行执行UPDATE子句完成更新,对于不带唯一约束的表,则仅执行插入。UPDATE时,可通过 "VALUES()" 来选择源数据相应的列。
- 如果表中存在多个唯一约束,如果所插入数据违反多个唯一约束,对于检测到冲突的第一行进行更新,其他冲突行不更新(检查顺序与索引维护具有强相关性,一般先创建的索引先进行冲突检查)。
- 如果插入多行,这些行均与表中同一行数据存在唯一约束冲突,则按照顺序,第一条执行插入或更新,之后依次执行更新。
- 主键、唯一索引列不允许UPDATE。
- expression不支持使用子查询表达式。
- 如果query为子查询,则不支持使用子查询中的列名。
- ON DUPLICATE KEY UPDATE子句更新多列时,前面UPDATE的结果不会影响后面的结果,且不支持同一列设置多次。
- view_name
要插入的目标视图。
对视图的插入,有如下约束:
- 只有直接引用基表用户列的列可插入。
- 视图必须至少包含一个可更新列,关于可更新列请参见CREATE VIEW。
- 不支持在顶层包含DISTINCT、GROUP BY、HAVING、LIMIT、OFFSET子句的视图。
- 不支持在顶层包含集合运算(UNION以及EXCEPT)的视图。
- 不支持目标列表中包含聚集函数、窗口函数、返回集合函数(array_agg、json_agg、generate_series等)的视图。
- 不支持ON DUPLICATE KEY UPDATE功能。
- 视图中支持的表类型包括普通表、临时表、全局临时表、分区表、ustore表、astore表。
- 对多表连接视图,一次只能对一张基表做插入。
- 对连接视图插入时显式指定的插入列或隐式指定(即创建视图中指定的列)不能引用非保留键表的列。关于保留键表请参见CREATE VIEW。
- 不支持对系统视图插入。
示例
- 插入一条数据
示例:
--建表。 m_db=# CREATE TABLE test_t1(col1 INT,col2 VARCHAR(20)); --插入数据。 m_db=# INSERT INTO test_t1 (col1, col2) VALUES (1,'AB'); --只给表中部分列插入数据。 m_db=# INSERT INTO test_t1 (col1) VALUES (2); --VALUES关键字左边没有括号,右边括号里面必须严格按照表结构的顺序给所有的字段添加值。 m_db=# INSERT INTO test_t1 VALUES (3,'AC'); --查询表。 m_db=# SELECT * FROM test_t1 ORDER BY col1; col1 | col2 ------+------ 1 | AB 2 | 3 | AC (3 rows) --删除表。 m_db=# DROP TABLE test_t1; - 插入多条数据
示例:
--建表。 m_db=# CREATE TABLE test_t2(col1 INT,col2 VARCHAR(20)); m_db=# CREATE TABLE test_t3(col1 INT,col2 VARCHAR(20)); --插入多条数据。 m_db=# INSERT INTO test_t2 (col1, col2) VALUES (10,'AA'),(20,'BB'),(30,'CC'); --查询表。 m_db=# SELECT * FROM test_t2; col1 | col2 ------+------ 10 | AA 20 | BB 30 | CC (3 rows) --把test_t2中的数据插入到test_t3中。 m_db=# INSERT INTO test_t3 SELECT * FROM test_t2; --查询表。 m_db=# SELECT * FROM test_t3; col1 | col2 ------+------ 10 | AA 20 | BB 30 | CC (3 rows) --删除表。 m_db=# DROP TABLE test_t2; m_db=# DROP TABLE test_t3;
- ON DUPLICATE KEY UPDATE
示例:
-- 建表。 m_db=# CREATE TABLE test_t4 (id INT PRIMARY KEY, info VARCHAR(10)); m_db=# INSERT INTO test_t4 VALUES (1, 'AA'), (2,'BB'), (3, 'CC'); -- 使用ON DUPLICATE KEY UPDATE关键字。 m_db=# INSERT INTO test_t4 VALUES (3, 'DD'), (4, 'EE') ON DUPLICATE KEY UPDATE info = VALUES(info); -- 查询表。 m_db=# SELECT * FROM test_t4; id | info ----+------ 1 | AA 2 | BB 4 | EE 3 | DD -- 删除表。 m_db=# DROP TABLE test_t4;
- INSERT IGNORE
示例1:破坏NOT NULL约束
--建表。 m_db=# CREATE TABLE test_t5(f1 INT NOT NULL); CREATE TABLE --使用IGNORE关键字。 m_db=# INSERT IGNORE INTO test_t5 VALUES(NULL); WARNING: null value in column "f1" violates not-null constraint DETAIL: Failing row contains (null). INSERT 0 1 --查询表。 m_db=# SELECT * FROM test_t5; f1 ---- 0 (1 row) --删除表。 m_db=# DROP TABLE test_t5;
示例2:唯一键冲突
--建表。 m_db=# CREATE TABLE test_t6(f1 INT PRIMARY KEY); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_t6_pkey" for table "test_t6" CREATE TABLE --插入数据。 m_db=# INSERT INTO test_t6 VALUES(1); INSERT 0 1 --使用IGNORE关键字。 m_db=# INSERT IGNORE INTO test_t6 VALUES(1); WARNING: duplicate key value violates unique constraint "test_t6_pkey" INSERT 0 0 --查询表。 m_db=# SELECT * FROM test_t6; f1 ---- 1 (1 row) --删除表。 m_db=# DROP TABLE test_t6; DROP TABLE
示例3:插入的值没有找到对应的分区
--建表。 m_db=# CREATE TABLE test_t7(f1 INT, f2 INT) PARTITION BY LIST(f1) (PARTITION p0 VALUES(1, 4, 7), PARTITION p1 VALUES (2, 5, 8)); CREATE TABLE --使用IGNORE关键字。 m_db=# INSERT IGNORE INTO test_t7 VALUES(3, 5); WARNING: inserted partition key does not map to any table partition INSERT 0 0 --查询表。 m_db=# SELECT * FROM test_t7; f1 | f2 ----+---- (0 rows) --删除表。 m_db=# DROP TABLE test_t7; DROP TABLE
示例4:指定分区插入时,插入的数据与指定的分区不匹配
--建表。 m_db=# CREATE TABLE test_t8(f1 INT NOT NULL, f2 TEXT, f3 INT) PARTITION BY RANGE(f1)(PARTITION p0 VALUES LESS THAN(5), PARTITION p1 VALUES LESS THAN(10), PARTITION p2 VALUES LESS THAN(15), PARTITION p3 VALUES LESS THAN(MAXVALUE)); CREATE TABLE --使用IGNORE关键字。 m_db=# INSERT IGNORE INTO test_t8 PARTITION(p2) VALUES(20, 'Jan', 1); WARNING: inserted partition key does not map to the table partition DETAIL: N/A. INSERT 0 0 --查询表。 m_db=# SELECT * FROM test_t8; f1 | f2 | f3 ----+----+---- (0 rows) --删除表。 m_db=# DROP TABLE test_t8; DROP TABLE
示例5:子查询返回多行
--建表。 m_db=# CREATE TABLE test_t9(f1 INT, f2 INT); CREATE TABLE --插入数据。 m_db=# INSERT INTO test_t9 VALUES(1, 1), (2, 2), (3, 3); INSERT 0 3 --使用IGNORE关键字。 m_db=# INSERT IGNORE INTO test_t9 VALUES((SELECT f1 FROM test_t9), 0); WARNING: more than one row returned by a subquery used as an expression CONTEXT: referenced column: f1 INSERT 0 1 --查询表。 m_db=# SELECT * FROM test_t9 WHERE f2 = 0; f1 | f2 ----+---- | 0 (1 row) --删除表。 m_db=# DROP TABLE test_t9; DROP TABLE - 插入视图
示例:
--创建SCHEMA。 m_db=# CREATE SCHEMA ins_view; CREATE SCHEMA m_db=# SET CURRENT_SCHEMA = 'ins_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 VIEW v_ins1 AS SELECT * FROM t1; CREATE VIEW m_db=# CREATE VIEW v_ins2 AS SELECT * FROM t1 WHERE y1 < 3; CREATE VIEW --通过视图对t1插入。 m_db=# INSERT INTO v_ins1 VALUES (1, 1); INSERT 0 1 m_db=# INSERT INTO v_ins2 VALUES (5, 5); INSERT 0 1 --创建多表视图。 m_db=# CREATE VIEW vv_ins AS SELECT * FROM t1, t2 WHERE x1 = x2; CREATE VIEW --通过多表视图对t1插入。 m_db=# INSERT INTO vv_ins (x1, y1) VALUES (2, 2); INSERT 0 1 --删除SCHEMA。 m_db=# DROP SCHEMA ins_view; NOTICE: drop cascades to 5 other objects DETAIL: drop cascades to table t1 drop cascades to table t2 drop cascades to view v_ins1 drop cascades to view v_ins2 drop cascades to view vv_ins DROP SCHEMA