INSERT 语句用来向表中插入行记录。

最简单的 INSERT 语句语法格式如下:

  1. INSERT INTO table_name (list_of_columns) VALUES (list_of_values);

其中,list_of_columns 指定表的 table_name 列,list_of_values 是 list_of_columns 提到的列的对应值,必须一一对应。因此,在向一个表插入记录之前,需要了解这个表所有的列信息,以及列类型和有效值、是否允许为空等。在 obclient 命令行环境下,可以直接用 DESC 命令查看列属性,如下所示:

  1. obclient> desc ordl;
  2. +----------------+-------------+------+-----+---------+-------+
  3. | FIELD | TYPE | NULL | KEY | DEFAULT | EXTRA |
  4. +----------------+-------------+------+-----+---------+-------+
  5. | OL_W_ID | NUMBER(38) | NO | PRI | NULL | NULL |
  6. | OL_D_ID | NUMBER(38) | NO | PRI | NULL | NULL |
  7. | OL_O_ID | NUMBER(38) | NO | PRI | NULL | NULL |
  8. | OL_NUMBER | NUMBER(38) | NO | PRI | NULL | NULL |
  9. | OL_DELIVERY_D | DATE | YES | NULL | NULL | NULL |
  10. | OL_AMOUNT | NUMBER(6,2) | YES | NULL | NULL | NULL |
  11. | OL_I_ID | NUMBER(38) | YES | NULL | NULL | NULL |
  12. | OL_SUPPLY_W_ID | NUMBER(38) | YES | NULL | NULL | NULL |
  13. | OL_QUANTITY | NUMBER(38) | YES | NULL | NULL | NULL |
  14. | OL_DIST_INFO | CHAR(24) | YES | NULL | NULL | NULL |
  15. +----------------+-------------+------+-----+---------+-------+
  16. 10 rows in set (0.01 sec)

在 INSERT 语句中,您不需要知道表的所有列的值,但需要知道所有列属性为 NOT NULL 的列的值。如果列属性为NOT NULL 有默认值时,您可以不指定该列的值;如果列为 NULL,您也可以不指定该列的值,OceanBase 会在该列上插入一个 NULL 值。

当插入多条件记录时,可以分多条 INSERT 语句,也可以用一个 INSERT 多个 VALUES 语句。

示例:当所有列信息都知道时,使用INSERT语句

如下示例创建有默认值列的表,SQL 插入两笔记录,所有字段信息都有值。

  1. obclient> CREATE TABLE t_insert(
  2. id number NOT NULL PRIMARY KEY
  3. , name varchar(10) NOT NULL, value number
  4. , gmt_create date NOT NULL DEFAULT sysdate
  5. );
  6. Query OK, 0 rows affected (0.07 sec)
  7. obclient> INSERT INTO t_insert(id, name, value, gmt_create)
  8. values(1,'CN',10001, sysdate);
  9. Query OK, 1 row affected (0.01 sec)

示例:当不是所有列信息都知道时,使用INSERT语句

下面 SQL 插入两笔记录,gmt_create 字段没有提供。两笔记录使用一个 INSERT 多个 VALUES 子句。

  1. obclient> INSERT INTO t_insert(id, name, value)
  2. VALUES (2,'US', 10002) ,(3,'EN', 10003);
  3. Query OK, 2 rows affected (0.00 sec)
  4. Records: 2 Duplicates: 0 Warnings: 0

示例:使用INSERT语句违反唯一约束冲突

当表上有唯一性约束的时候,插入相同的记录,数据库会报错,提示 key ‘xxx’ violated。

  1. obclient> INSERT INTO t_insert(id, name, value)
  2. VALUES (3,'UK', 10003)
  3. ,(4, 'JP', 10004);
  4. ERROR-00001: unique constraint '3' for key 'PRIMARY' violated

这个报错可以通过 INSERT IGNORE INTO、MERGE INTO、INSERT INTO ON DUPLICATE KEY UPDATE 避免。

关于INSERT IGNORE INTO 语句

下面示例是 MySQL 租户下 INSERT 用法,以及使用 INSERT IGNORE INTO 避免约束冲突。IGNORE 关键字可以忽略由于约束冲突导致的 INSERT 失败的影响。

  1. obclient> CREATE TABLE t_insert(
  2. id number NOT NULL PRIMARY KEY
  3. , name varchar(10) NOT NULL
  4. , value number
  5. ,gmt_create timestamp NOT NULL DEFAULT current_timestamp
  6. );
  7. Query OK, 0 rows affected (0.68 sec)
  8. obclient> INSERT INTO t_insert(id, name, value, gmt_create)
  9. VALUES (1,'CN',10001, current_timestamp);
  10. Query OK, 1 row affected (0.01 sec)
  11. obclient> INSERT INTO t_insert(id, name, value)
  12. VALUES (2,'US', 10002),(3,'EN', 10003);
  13. Query OK, 2 rows affected (0.00 sec)
  14. Records: 2 Duplicates: 0 Warnings: 0
  15. obclient> INSERT INTO t_insert(id, name, value)
  16. VALUES (3,'UK', 10003),(4, 'JP', 10004);
  17. ERROR 1062 (23000): Duplicate entry '3' for key 'PRIMARY'
  18. obclient>
  19. obclient> INSERT IGNORE INTO t_insert(id, name, value)
  20. VALUES (3,'UK', 10003) ,(4, 'JP', 10004);
  21. Query OK, 1 row affected (0.00 sec)
  22. obclient> select * from t_insert;
  23. +----+------+-------+---------------------+
  24. | id | name | value | gmt_create |
  25. +----+------+-------+---------------------+
  26. | 1 | CN | 10001 | 2020-04-03 16:05:45 |
  27. | 2 | US | 10002 | 2020-04-03 16:05:54 |
  28. | 3 | EN | 10003 | 2020-04-03 16:05:54 |
  29. | 4 | JP | 10004 | 2020-04-03 16:06:08 |
  30. +----+------+-------+---------------------+
  31. 4 rows in set (0.00 sec)

示例:使用查询语句充当 INSERT 的 values 子句

当需要备份一个表的备份或者全部记录时,可以使用 INSERT INTO … SELECT … FROM 语句。

  1. obclient> create table ware_bak(
  2. w_id int
  3. , w_ytd decimal(12,2)
  4. , w_tax decimal(4,4)
  5. , w_name varchar(10)
  6. , w_street_1 varchar(20)
  7. , w_street_2 varchar(20)
  8. , w_city varchar(20)
  9. , w_state char(2)
  10. , w_zip char(9)
  11. , primary key(w_id)
  12. );
  13. Query OK, 0 rows affected (0.17 sec)
  14. obclient> insert into ware_bak select * from ware;
  15. Query OK, 2 rows affected (0.02 sec)
  16. Records: 2 Duplicates: 0 Warnings: 0