云服务器内容精选

  • 注意事项 只有拥有表INSERT权限的用户,才可以向表中插入数据。用户被授予INSERT ANY TABLE权限,相当于用户对除系统模式之外的任何模式具有USAGE权限,并且拥有这些模式下表的INSERT权限。 如果使用RETURNING子句,用户必须要有该表的SELECT权限。 如果使用ON DUPLICATE KEY UPDATE,用户必须要有该表的INSERT、UPDATE权限,UPDATE子句中列的SELECT权限。 如果使用query子句插入来自查询里的数据行,用户还需要拥有在查询里使用的表的SELECT权限。 生成列不能被直接写入。在INSERT命令中不能为生成列指定值,但是可以指定关键字DEFAULT。 当连接到TD兼容的数据库时,td_compatible_truncation参数设置为on时,将启用超长字符串自动截断功能,在后续的INSERT语句中(不包含外表的场景下),对目标表中CHAR和VARCHAR类型的列上插入超长字符串时,系统会自动按照目标表中相应列定义的最大长度对超长字符串进行截断。 如果向字符集为字节类型编码(SQL_ASCII,LATIN1等)的数据库中插入多字节字符数据(如汉字等),且字符数据跨越截断位置,这种情况下,按照字节长度自动截断,自动截断后会在尾部产生非预期结果。如果用户有对于截断结果正确性的要求,建议用户采用UTF8等能够按照字符截断的输入字符集作为数据库的编码集。
  • 示例 插入一条数据 示例: --建表。 gaussdb=# CREATE TABLE test_t1(col1 INT,col2 VARCHAR); --插入数据。 gaussdb=# INSERT INTO test_t1 (col1, col2) VALUES (1,'AB'); --只给表中部分列插入数据。 gaussdb=# INSERT INTO test_t1 (col1) VALUES (2); --VALUES关键字左边没有括号,右边括号里面必须严格按照表结构的顺序给所有的字段添加值。 gaussdb=# INSERT INTO test_t1 VALUES (3,'AC'); --查询表。 gaussdb=# SELECT * FROM test_t1; col1 | col2 ------+------ 1 | AB 2 | 3 | AC (3 rows) --删除表。 gaussdb=# DROP TABLE test_t1; 插入多条数据 示例: --建表。 gaussdb=# CREATE TABLE test_t2(col1 INT,col2 VARCHAR); gaussdb=# CREATE TABLE test_t3(col1 INT,col2 VARCHAR); --插入多条数据。 gaussdb=# INSERT INTO test_t2 (col1, col2) VALUES (10,'AA'),(20,'BB'),(30,'CC'); --查询表。 gaussdb=# SELECT * FROM test_t2; col1 | col2 ------+------ 10 | AA 20 | BB 30 | CC (3 rows) --把test_t2中的数据插入到test_t3中。 gaussdb=# INSERT INTO test_t3 SELECT * FROM test_t2; --查询表。 gaussdb=# SELECT * FROM test_t3; col1 | col2 ------+------ 10 | AA 20 | BB 30 | CC (3 rows) --删除表。 gaussdb=# DROP TABLE test_t2; gaussdb=# DROP TABLE test_t3; ON DUPLICATE KEY UPDATE 示例: --建表。 gaussdb=# CREATE TABLE test_t4 (id INT PRIMARY KEY, info VARCHAR(10)); gaussdb=# INSERT INTO test_t4 VALUES (1, 'AA'), (2,'BB'), (3, 'CC'); --使用ON DUPLICATE KEY UPDATE关键字。 gaussdb=# INSERT INTO test_t4 VALUES (3, 'DD'), (4, 'EE') ON DUPLICATE KEY UPDATE info = VALUES(info); --查询表。 gaussdb=# SELECT * FROM test_t4; id | info ----+------ 1 | AA 2 | BB 4 | EE 3 | DD --删除表。 gaussdb=# DROP TABLE test_t4; INSERT IGNORE 示例1:破坏NOT NULL约束 --创建B兼容模式数据库。 gaussdb=# CREATE DATABASE test DBCOMPATIBILITY ='B'; gaussdb=# \c test --设置前置参数。 test=# set b_format_version = '5.7'; test=# set b_format_dev_version = 's1'; --建表。 test=# CREATE TABLE test_t5(f1 INT NOT NULL); CREATE TABLE --使用IGNORE关键字。 test=# 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 --查询表。 test=# SELECT * FROM test_t5; f1 ---- 0 (1 row) --删除表。 test=# DROP TABLE test_t5; 示例2:唯一键冲突 --建表。 test=# 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 --插入数据。 test=# INSERT INTO test_t6 VALUES(1); INSERT 0 1 --使用IGNORE关键字。 test=# INSERT IGNORE INTO test_t6 VALUES(1); WARNING: duplicate key value violates unique constraint "test_t6_pkey" INSERT 0 0 --查询表。 test=# SELECT * FROM test_t6; f1 ---- 1 (1 row) --删除表。 test=# DROP TABLE test_t6; DROP TABLE 示例3:插入的值没有找到对应的分区 --建表。 test=# 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关键字。 test=# INSERT IGNORE INTO test_t7 VALUES(3, 5); WARNING: inserted partition key does not map to any table partition INSERT 0 0 --查询表。 test=# SELECT * FROM test_t7; f1 | f2 ----+---- (0 rows) --删除表。 test=# DROP TABLE test_t7; DROP TABLE 示例4:指定分区插入时,插入的数据与指定的分区不匹配 --建表。 test=# 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关键字。 test=# 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 --查询表。 test=# SELECT * FROM test_t8; f1 | f2 | f3 ----+----+---- (0 rows) --删除表。 test=# DROP TABLE test_t8; DROP TABLE 示例5:子查询返回多行 --建表。 test=# CREATE TABLE test_t9(f1 INT, f2 INT); CREATE TABLE --插入数据。 test=# INSERT INTO test_t9 VALUES(1, 1), (2, 2), (3, 3); INSERT 0 3 --使用IGNORE关键字。 test=# 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 --查询表。 test=# SELECT * FROM test_t9 WHERE f2 = 0; f1 | f2 ----+---- | 0 (1 row) --删除表。 test=# DROP TABLE test_t9; DROP TABLE 示例6:数据过长 --建表。 test=# CREATE TABLE test_t10(f1 VARCHAR(5)); CREATE TABLE --使用IGNORE关键字。 test=# INSERT IGNORE INTO test_t10 VALUES('aaaaaaaaa'); WARNING: value too long for type character varying(5) CONTEXT: referenced column: f1 INSERT 0 1 --查询表。 test=# SELECT * FROM test_t10; f1 ------- aaaaa (1 row) --删除表。 test=# DROP TABLE test_t10; DROP TABLE 示例7:时间函数溢出 --建表。 test=# CREATE TABLE test_t11(f1 DATETIME); CREATE TABLE --使用IGNORE关键字。 test=# INSERT IGNORE INTO test_t11 VALUES(date_sub('2000-01-01', INTERVAL 2001 YEAR)); WARNING: Datetime function: datetime field overflow CONTEXT: referenced column: f1 INSERT 0 1 --查询表。 test=# SELECT * FROM test_t11; f1 ---- (1 row) --删除表。 test=# DROP TABLE test_t11; DROP TABLE 示例8:被0除 --建表。 test=# CREATE TABLE test_t12(f1 INT); CREATE TABLE --使用IGNORE关键字。 test=# INSERT IGNORE INTO test_t12 VALUES(1/0); WARNING: division by zero CONTEXT: referenced column: f1 INSERT 0 1 --查询表。 test=# SELECT * FROM test_t12; f1 ---- (1 row) --删除表。 test=# DROP TABLE test_t12; DROP TABLE 示例9:值不正确 --建表。 test=# CREATE TABLE test_t13(f1 FLOAT); CREATE TABLE --使用IGNORE关键字。 test=# INSERT IGNORE INTO test_t13 VALUES('1.11aaa'); WARNING: invalid input syntax for type real: "1.11aaa" LINE 1: INSERT IGNORE INTO test_t13 VALUES('1.11aaa'); ^ CONTEXT: referenced column: f1 INSERT 0 1 --查询表。 test=# SELECT * FROM test_t13; f1 ------ 1.11 (1 row) --删除表。 test=# DROP TABLE test_t13; --删除数据库(请根据实际情况修改数据库名)。 test=# \c test; test=# DROP DATABASE test; WITH [ RECURSIVE ] with_query [, ...] 示例: --成绩表。 gaussdb=# CREATE TABLE grade ( sid INT, course VARCHAR(20), score FLOAT ); --学生表。 gaussdb=# CREATE TABLE student( sid INT PRIMARY KEY, class INT, name VARCHAR(50), sex INT CHECK (sex = 0 or sex = 1) ); --插入数据。 gaussdb=# WITH student_sid AS ( INSERT INTO student ( sid, CLASS, NAME, sex ) VALUES ( 1, 1, 'Scott', 1 ) RETURNING sid ) INSERT INTO grade ( sid, course, score ) VALUE ( ( SELECT sid FROM student_sid ), 'math', '96' ), ( ( SELECT sid FROM student_sid ), 'chinese', '82' ), ( ( SELECT sid FROM student_sid ), 'english', '86' ); --查询表。 gaussdb=# SELECT * FROM student; sid | class | name | sex -----+-------+-------+----- 1 | 1 | scott | 1 (1 row) gaussdb=# SELECT * FROM grade; sid | course | score -----+---------+------- 1 | math | 96 1 | chinese | 82 1 | english | 86 (3 rows) --删除表。 gaussdb=# DROP TABLE student; gaussdb=# DROP TABLE grade;
  • 语法格式 [ WITH [ RECURSIVE ] with_query [, ...] ] INSERT [/*+ plan_hint */] [ IGNORE ] INTO table_name [ { [alias_name] [ ( column_name [, ...] ) ] } | { [partition_clause] [ AS alias ] [ ( column_name [, ...] ) ] } ] { DEFAULT VALUES | { VALUES | VALUE } {( { expression | DEFAULT } [, ...] ) }[, ...] | query } [ ON DUPLICATE KEY UPDATE { NOTHING | { column_name = { expression | DEFAULT } } [, ...] [ WHERE condition ] }] [ RETURNING {* | {output_expression [ [ AS ] output_name ] }[, ...]} ];
  • 优化建议 VALUES 通过INSERT语句批量插入数据时,建议将多条记录合并入一条语句中执行插入,以提高数据加载性能。 例如: INSERT INTO sections VALUES (30, 'Administration', 31, 1900),(40, 'Development', 35, 2000), (50, 'Development' , 60 , 2001); 如果INSERT多VALUES语句中VALUES的值分布在一个DN上, GaussDB 可以把语句下推到对应DN执行。目前只支持VALUES中值为常量,简单表达式和可下推函数(pg_proc中字段provolatile为'i')。如果表中列带有DEFAULT值,只支持DEFAULT值为常量,简单表达式。单VALUES不能下推单DN的语句,多VALUES同样不支持下推。
  • 语法格式 1 2 3 4 5 6 7 [ WITH [ RECURSIVE ] with_query [, ...] ] INSERT [/*+ plan_hint */] [ IGNORE ] INTO table_name [ { [alias_name] [ ( column_name [, ...] ) ] } | { [partition_clause] [ AS alias ] [ ( column_name [, ...] ) ] } ] { DEFAULT VALUES | { VALUES | VALUE } {( { expression | DEFAULT } [, ...] ) }[, ...] | query } [ ON DUPLICATE KEY UPDATE { NOTHING | { column_name = { expression | DEFAULT } } [, ...] [ WHERE condition ] } ] [ RETURNING {* | {output_expression [ [ AS ] output_name ] }[, ...]} ];
  • 示例 插入一条数据 示例: --建表。 gaussdb=# CREATE TABLE test_t1(col1 INT,col2 VARCHAR); --插入数据。 gaussdb=# INSERT INTO test_t1 (col1, col2) VALUES (1,'AB'); --只给表中部分列添加值。 gaussdb=# INSERT INTO test_t1 (col1) VALUES (2); --VALUES关键字左边没有括号,右边括号里面必须严格按照表结构的顺序给所有的字段添加值。 gaussdb=# INSERT INTO test_t1 VALUES (3,'AC'); --查询表。 gaussdb=# SELECT * FROM test_t1; col1 | col2 ------+------ 1 | AB 2 | 3 | AC (3 rows) --删除。 gaussdb=# DROP TABLE test_t1; 插入多条数据 示例: --建表。 gaussdb=# CREATE TABLE test_t2(col1 INT,col2 VARCHAR); gaussdb=# CREATE TABLE test_t3(col1 INT,col2 VARCHAR); --插入多条数据。 gaussdb=# INSERT INTO test_t2 (col1, col2) VALUES (10,'AA'),(20,'BB'),(30,'CC'); --查询。 gaussdb=# SELECT * FROM test_t2; col1 | col2 ------+------ 10 | AA 20 | BB 30 | CC (3 rows) --把test_t2中的数据插入到test_t3中。 gaussdb=# INSERT INTO test_t3 SELECT * FROM test_t2; --查询。 gaussdb=# SELECT * FROM test_t3; col1 | col2 ------+------ 10 | AA 20 | BB 30 | CC (3 rows) --删除。 gaussdb=# DROP TABLE test_t2; DROP TABLE test_t3; ON DUPLICATE KEY UPDATE 示例: --建表。 gaussdb=# CREATE TABLE test_t4 (id INT PRIMARY KEY, info VARCHAR(10)); gaussdb=# INSERT INTO test_t4 VALUES (1, 'AA'), (2,'BB'), (3, 'CC'); --使用ON DUPLICATE KEY UPDATE关键字。 gaussdb=# INSERT INTO test_t4 VALUES (3, 'DD'), (4, 'EE') ON DUPLICATE KEY UPDATE info = VALUES(info); --查询。 gaussdb=# SELECT * FROM test_t4; id | info ----+------ 1 | AA 2 | BB 4 | EE 3 | DD --删除。 gaussdb=# DROP TABLE test_t4; INSERT IGNORE 示例1:破坏NOT NULL约束 --建表。 gaussdb=# CREATE TABLE test_t5(f1 INT NOT NULL); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'f1' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE --使用IGNORE关键字。 gaussdb=# 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 --查询表。 gaussdb=# SELECT * FROM test_t5; f1 ---- 0 (1 row) --删除表。 gaussdb=# DROP TABLE test_t5; DROP TABLE 示例2:唯一键冲突 --建表。 gaussdb=# 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 --插入数据。 gaussdb=# INSERT INTO test_t6 VALUES(1); INSERT 0 1 --使用IGNORE关键字。 gaussdb=# INSERT IGNORE INTO test_t6 VALUES(1); INSERT 0 0 --查询表。 gaussdb=# SELECT * FROM test_t6; f1 ---- 1 (1 row) --删除表。 gaussdb=# DROP TABLE test_t6; DROP TABLE 示例3:插入的值没有找到对应的分区 --建表。 gaussdb=# CREATE TABLE test_t7(f1 INT, f2 INT) PARTITION BY LIST(f1) (PARTITION p0 VALUES(1, 4, 7), PARTITION p1 VALUES (2, 5, 8)); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'f1' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE --使用IGNORE关键字。 gaussdb=# INSERT IGNORE INTO test_t7 VALUES(3, 5); INSERT 0 0 --查询表。 gaussdb=# SELECT * FROM test_t7; f1 | f2 ----+---- (0 rows) --删除表。 gaussdb=# DROP TABLE test_t7; DROP TABLE 示例4:指定分区插入时,插入的数据与指定的分区不匹配 --建表。 gaussdb=# 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)); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'f1' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE --使用IGNORE关键字。 gaussdb=# INSERT IGNORE INTO test_t8 PARTITION(p2) VALUES(20, 'Jan', 1); INSERT 0 0 --查询表。 gaussdb=# SELECT * FROM test_t8; f1 | f2 | f3 ----+----+---- (0 rows) --删除表。 gaussdb=# DROP TABLE test_t8; DROP TABLE 示例5:子查询返回多行 --建表。 gaussdb=# CREATE TABLE test_t9(f1 INT, f2 INT); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'f1' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE --插入数据。 gaussdb=# INSERT INTO test_t9 VALUES(1, 1), (2, 2), (3, 3); INSERT 0 3 --使用IGNORE关键字。 gaussdb=# 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 --查询表。 gaussdb=# SELECT * FROM test_t9 WHERE f2 = 0; f1 | f2 ----+---- | 0 (1 row) --删除表。 gaussdb=# DROP TABLE test_t9; DROP TABLE 示例6:数据过长 --建表。 gaussdb=# CREATE TABLE test_t10(f1 VARCHAR(5)); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'f1' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE --使用IGNORE关键字。 gaussdb=# INSERT IGNORE INTO test_t10 VALUES('aaaaaaaaa'); WARNING: value too long for type character varying(5) CONTEXT: referenced column: f1 INSERT 0 1 --查询表。 gaussdb=# SELECT * FROM test_t10; f1 ------- aaaaa (1 row) --删除表。 gaussdb=# DROP TABLE test_t10; DROP TABLE 示例7:时间函数溢出 --建表。 gaussdb=# CREATE TABLE test_t11(f1 DATETIME); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'f1' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE --使用IGNORE关键字。 gaussdb=# INSERT IGNORE INTO test_t11 VALUES(date_sub('2000-01-01', INTERVAL 2001 YEAR)); WARNING: Datetime function: datetime field overflow CONTEXT: referenced column: f1 INSERT 0 1 --查询表。 gaussdb=# SELECT * FROM test_t11; f1 ---- (1 row) --删除表。 gaussdb=# DROP TABLE test_t11; DROP TABLE 示例8:被0除 --建表。 gaussdb=# CREATE TABLE test_t12(f1 INT); CREATE TABLE --使用IGNORE关键字。 gaussdb=# INSERT IGNORE INTO test_t12 VALUES(1/0); WARNING: division by zero CONTEXT: referenced column: f1 INSERT 0 1 --查询表。 gaussdb=# SELECT * FROM test_t12; f1 ---- (1 row) --删除表。 gaussdb=# DROP TABLE test_t12; DROP TABLE 示例9:值不正确 --建表。 gaussdb=# CREATE TABLE test_t13(f0 INT, f1 FLOAT); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'f0' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE --使用IGNORE关键字。 gaussdb=# INSERT IGNORE INTO test_t13 VALUES(1, '1.11aaa'); WARNING: invalid input syntax for type real: "1.11aaa" LINE 1: INSERT IGNORE INTO test_t13 VALUES(1, '1.11aaa'); ^ CONTEXT: referenced column: f1 INSERT 0 1 --查询表。 gaussdb=# SELECT * FROM test_t13; f0 | f1 ----+------ 1 | 1.11 (1 row) --删除表。 gaussdb=# DROP TABLE test_t13; DROP TABLE WITH [ RECURSIVE ] with_query [, ...] 示例: --成绩表。 gaussdb=# CREATE TABLE grade ( sid INT, course VARCHAR(20), score FLOAT ); --学生表。 gaussdb=# CREATE TABLE student( sid INT PRIMARY KEY, class INT, name VARCHAR(50), sex INT CHECK (sex = 0 or sex = 1) ); --插入数据。 gaussdb=# WITH student_sid AS ( INSERT INTO student ( sid, CLASS, NAME, sex ) VALUES ( 1, 1, 'scott', 1 ) RETURNING sid ) INSERT INTO grade ( sid, course, score ) VALUE ( ( SELECT sid FROM student_sid ), 'match', '96' ), ( ( SELECT sid FROM student_sid ), 'chinese', '82' ), ( ( SELECT sid FROM student_sid ), 'english', '86' ); --查询数据。 gaussdb=# SELECT * FROM student; sid | class | name | sex -----+-------+-------+----- 1 | 1 | scott | 1 (1 row) gaussdb=# SELECT * FROM grade; sid | course | score -----+---------+------- 1 | match | 96 1 | chinese | 82 1 | english | 86 (3 rows) --删除。 gaussdb=# DROP TABLE student; gaussdb=# DROP TABLE grade;
  • 注意事项 表的所有者、拥有表INSERT权限的用户或拥有INSERT ANY TABLE权限的用户,可向表中插入数据,三权分立关闭时的系统管理员默认拥有此权限。 如果使用RETURNING子句,用户必须要有该表的SELECT权限。 如果使用ON DUPLICATE KEY UPDATE,用户必须要有该表的INSERT、UPDATE权限,UPDATE子句中列的SELECT权限。 如果使用query子句插入来自查询里的数据行,用户还需要拥有在查询里使用的表的SELECT权限。 如果使用query子句插入来自查询动态数据脱敏列的数据,插入的结果即为脱敏后的值,无法被还原。 当连接到TD兼容的数据库时,td_compatible_truncation参数设置为on时,将启用超长字符串自动截断功能,在后续的INSERT语句中(不包含外表的场景下),对目标表中CHAR和VARCHAR类型的列上插入超长字符串时,系统会自动按照目标表中相应列定义的最大长度对超长字符串进行截断。 如果向字符集为字节类型编码(SQL_ASCII,LATIN1等)的数据库中插入多字节字符数据(如汉字等),且字符数据跨越截断位置,这种情况下,按照字节长度自动截断,自动截断后会在尾部产生非预期结果。如果用户有对于截断结果正确性的要求,建议用户采用UTF8等能够按照字符截断的输入字符集作为数据库的编码集。