Insert Into 语句的使用方式和 MySQL 等数据库中 Insert Into 语句的使用方式类似。但在 Doris 中,所有的数据写入都是一个独立的导入作业。所以这里将 Insert Into 也作为一种导入方式介绍。
主要的 Insert Into 命令包含以下两种;
其中第二种命令仅用于 Demo,不要使用在测试或生产环境中。
Insert Into 命令需要通过 MySQL 协议提交,创建导入请求会同步返回导入结果。
语法:
INSERT INTO table_name [partition_info] [WITH LABEL label] [col_list] [query_stmt] [VALUES];
示例:
INSERT INTO site_visit WITH LABEL label1 SELECT * FROM site_visit3;
注意:
当需要使用 CTE(Common Table Expressions) 作为 insert 操作中的查询部分时,必须指定 WITH LABEL 和 column list 部分。示例
INSERT INTO site_visit WITH LABEL label1 SELECT * FROM site_visit3;
Insert Into 本身就是一个 SQL 命令,其返回结果会根据执行结果的不同,分为以下几种:
如果 insert 对应 select 语句的结果集为空,则返回如下:
mysql> insert into tbl1 select * from empty_tbl;
Query OK, 0 rows affected (0.02 sec)
Query OK 表示执行成功。0 rows affected 表示没有数据被导入。
在结果集不为空的情况下。返回结果分为如下几种情况:
(1)Insert 执行成功并可见:
mysql> insert into tbl1 select * from tbl2;
Query OK, 4 rows affected (0.38 sec)
{'label':'insert_8510c568-9eda-4173-9e36-6adc7d35291c', 'status':'visible', 'txnId':'4005'}
mysql> insert into tbl1 with label my_label1 select * from tbl2;
Query OK, 4 rows affected (0.38 sec)
{'label':'my_label1', 'status':'visible', 'txnId':'4005'}
mysql> insert into tbl1 select * from tbl2;
Query OK, 2 rows affected, 2 warnings (0.31 sec)
{'label':'insert_f0747f0e-7a35-46e2-affa-13a235f4020d', 'status':'visible', 'txnId':'4005'}
mysql> insert into tbl1 select * from tbl2;
Query OK, 2 rows affected, 2 warnings (0.31 sec)
{'label':'insert_f0747f0e-7a35-46e2-affa-13a235f4020d', 'status':'committed', 'txnId':'4005'}
Query OK 表示执行成功。4 rows affected 表示总共有4行数据被导入。2 warnings 表示被过滤的行数。
同时会返回一个 json 串:
{'label':'my_label1', 'status':'visible', 'txnId':'4005'}
{'label':'insert_f0747f0e-7a35-46e2-affa-13a235f4020d', 'status':'committed', 'txnId':'4005'}
{'label':'my_label1', 'status':'visible', 'txnId':'4005', 'err':'some other error'}
label 为用户指定的 label 或自动生成的 label。Label 是该 Insert Into 导入作业的标识。每个导入作业,都有一个在单 database 内部唯一的 Label。
status 表示导入数据是否可见。如果可见,显示 visible,如果不可见,显示 committed。
txnId 为这个 insert 对应的导入事务的 id。
err 字段会显示一些其他非预期错误。
当需要查看被过滤的行时,用户可以通过如下语句
show load where label="xxx";
返回结果中的 URL 可以用于查询错误的数据,具体见后面 查看错误行 小结。
数据不可见是一个临时状态,这批数据最终是一定可见的
可以通过如下语句查看这批数据的可见状态:
show transaction where id=4005;
返回结果中的 TransactionStatus 列如果为 visible,则表述数据可见。
(2)Insert 执行失败
执行失败表示没有任何数据被成功导入,并返回如下:
mysql> insert into tbl1 select * from tbl2 where k1 = "a";
ERROR 1064 (HY000): all partitions have no load data. url: http://10.74.167.16:8042/api/_load_error_log?file=__shard_2/error_log_insert_stmt_ba8bb9e158e4879-ae8de8507c0bf8a2_ba8bb9e158e4879_ae8de8507c0bf8a2
其中 ERROR 1064 (HY000): all partitions have no load data 显示失败原因。后面的 url 可以用于查询错误的数据,具体见后面 查看错误行 小结。
综上,对于 insert 操作返回结果的正确处理逻辑应为:
(1) 如果 rows affected 为 0,表示结果集为空,没有数据被导入。
(2)如果 rows affected 大于 0:
如果 status 为 committed,表示数据还不可见。需要通过 show transaction 语句查看状态直到 visible
如果 status 为 visible,表示数据导入成功。
(3)如果 warnings 大于 0,表示有数据被过滤,可以通过 show load 语句获取 url 查看被过滤的行