| REPLACE INTO语法兼容 | REPLACE | |
| LOAD DATA导入数据功能 | LOAD DATA | - LOAD DATA语法执行结果与MySQL严格模式一致,宽松模式暂未适配。例如当导入源数据包含非法字符时,GaussDB报错,MySQL严格模式下报错,宽松模式下对非法字符进行截断处理后导入。
-- GaussDB
gaussdb=# SET sql_mode='';
SET
gaussdb=# DROP TABLE IF EXISTS t1;
DROP TABLE
gaussdb=# CREATE TABLE t1(a text) CHARSET gbk;
CREATE TABLE
gaussdb=# SELECT unhex('1AFF1F') INTO OUTFILE '/tmp/3.data';
COPY 1
gaussdb=# LOAD DATA INFILE '/tmp/3.data' INTO TABLE t1 CHARACTER SET gbk;
ERROR: invalid byte sequence for encoding "GBK": 0xff 0x1f
CONTEXT: COPY t1, line 1.
gaussdb=# DROP TABLE t1;
DROP TABLE
-- MySQL
mysql> SET sql_mode='';
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TABLE IF EXISTS t1;
Query OK, 0 rows affected (0.02 sec)
mysql> CREATE TABLE t1(a text) CHARSET gbk;
Query OK, 0 rows affected (0.03 sec)
mysql> SELECT unhex('1AFF1F') INTO OUTFILE '/tmp/3.data';
Query OK, 1 row affected (0.00 sec)
mysql> LOAD DATA INFILE '/tmp/3.data' INTO TABLE t1 CHARACTER SET gbk;
Query OK, 1 row affected, 1 warning (0.01 sec)
Records: 1 Deleted: 0 Skipped: 0 Warnings: 1
mysql> SHOW warnings;
+---------+------+------------------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------------------+
| Warning | 1366 | Incorrect string value: '\xFF\x1F' for column 'a' at row 1 |
+---------+------+------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT hex(a) FROM t1;
+--------+
| hex(a) |
+--------+
| 1A |
+--------+
1 row in set (0.00 sec)
mysql> DROP TABLE t1;
Query OK, 0 rows affected (0.02 sec) - IGNORE与LOCAL参数功能仅为当导入数据与表中数据存在冲突时,忽略当前冲突行数据功能和当文件中字段数小于指定表中列数时自动为其余列填充默认值功能,其余功能暂未适配。
- 指定LOCAL关键字,且文件路径为相对路径时,文件从二进制目录下搜索;不指定LOCAL关键字,且文件路径为相对路径时,文件从数据目录下搜索。
- 语法中指定分隔符,转义字符,分行符等符号时,若指定为单引号,将导致词法解析错误。
- [(col_name_or_user_var [, col_name_or_user_var] ...)]指定列参数不支持重复指定列。
- [FIELDS TERMINATED BY 'string']指定换行符不能与[LINES TERMINATED BY 'string']分隔符相同。
- 执行LOAD DATA语法写入表中的数据若无法转换为表中数据类型格式时报错。
- 指定列时,仅支持指定为列名,不支持指定为用户变量。
- LOAD DATA SET表达式中不支持指定列名计算。
- 若set表达式返回值类型与对应列类型之间不存在隐式转换函数则报错。
- LOAD DATA不支持INSERT、DELETE触发器。
- LOAD DATA只能用于表,不能用于视图。
- Windows下的文件与Linux环境下文件默认换行符存在差异,LOAD DATA无法识别此场景会报错,建议用户导入时检查导入文件行结尾的换行符。
- 当源数据的字段数比目标表的字段数多时,GaussDB提示告警信息,MySQL在以下任一场景提示告警信息,其他场景报错。
- sql_mode未设置严格模式。
- 指定了IGNORE选项。
- 指定了LOCAL选项且未指定REPLACE选项。
- 当源数据文件尾以列分隔符结束时,MySQL按分隔符后无新列处理,GaussDB下按分隔符后包含一列空字符串处理。
-- 1.csv源数据
1,2,
-- GaussDB
gaussdb=# DROP TABLE IF EXISTS t1;
NOTICE: table "t1" does not exist, skipping
DROP TABLE
gaussdb=# CREATE TABLE t1(a char(30), b char(30), c char(30));
CREATE TABLE
gaussdb=# LOAD DATA infile '/tmp/1.csv' INTO TABLE t1 fields terminated by ',';
COPY 1
gaussdb=# SELECT c IS NULL, length(c) FROM t1;
?column? | length
----------+--------
f | 0
(1 row)
-- MySQL
mysql> DROP TABLE IF EXISTS t1;
Query OK, 0 rows affected (0.06 sec)
mysql> CREATE TABLE t1(a char(30), b char(30), c char(30));
Query OK, 0 rows affected (0.04 sec)
mysql> LOAD DATA infile '/tmp/1.csv' INTO TABLE t1 fields terminated by ',';
ERROR 1261 (01000): Row 1 doesn't contain data for all columns |
| INSERT IGNORE兼容 | INSERT IGNORE | - GaussDB会返回降级后的错误信息,MySQL则会将降级后的错误信息记录到错误堆栈中,然后调用show warnings;命令查看。例如:
- 时间类型的差异。例如:
- GaussDB中date、datetime、timestamp默认零值。
gaussdb=# CREATE TABLE test(f1 DATE NOT NULL, f2 DATETIME NOT NULL, f3 TIMESTAMP NOT NULL);
CREATE TABLE
gaussdb=# INSERT IGNORE INTO test VALUES(NULL, NULL, NULL);
WARNING: null value in column "f1" violates not-null constraint
DETAIL: Failing row contains (null, null, null, null).
WARNING: null value in column "f2" violates not-null constraint
DETAIL: Failing row contains (null, null, null, null).
WARNING: null value in column "f3" violates not-null constraint
DETAIL: Failing row contains (null, null, null, null).
INSERT 0 1
gaussdb=#
SELECT * FROM test;
f1 | f2 | f3
------------+---------------------+---------------------
1970-01-01 | 1970-01-01 00:00:00 | 1970-01-01 00:00:00
(1 row) - MySQL中date、datetime、timestamp默认零值。
mysql> CREATE TABLE test(f1 DATE NOT NULL, f2 DATETIME NOT NULL, f3 TIMESTAMP NOT NULL);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT IGNORE INTO test VALUES(NULL, NULL, NULL);
Query OK, 1 row affected, 3 warnings (0.00 sec)
mysql> show warnings;
+---------+------+----------------------------+
| Level | Code | Message |
+---------+------+----------------------------+
| Warning | 1048 | Column 'f1' cannot be null |
| Warning | 1048 | Column 'f2' cannot be null |
| Warning | 1048 | Column 'f3' cannot be null |
+---------+------+----------------------------+
3 rows in set (0.00 sec)
mysql> SELECT * FROM test;
+------------+---------------------+---------------------+
| f1 | f2 | f3 |
+------------+---------------------+---------------------+
| 0000-00-00 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
+------------+---------------------+---------------------+
1 row in set (0.00 sec) - 由于GaussDB不支持MySQL的bit类型,因此忽略bit类型NOT NULL约束和插入的bit类型长度与定义不同的场景下不支持INSERT IGNORE错误降级。
- GaussDB中bit类型
gaussdb=# CREATE TABLE test(f1 BIT(10) NOT NULL);
CREATE TABLE
gaussdb=# INSERT IGNORE INTO test VALUES(NULL);
ERROR: Un-support feature
DETAIL: ignore null for insert statement is not supported in column f1.
gaussdb=# INSERT IGNORE INTO test VALUES('1010');
ERROR: bit string length 4 does not match type bit(10)
CONTEXT: referenced column: f1 -
MySQL中bit类型 mysql> CREATE TABLE test(f1 BIT(10) NOT NULL);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT IGNORE INTO test VALUES(NULL);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> INSERT IGNORE INTO test VALUES('1010');
Query OK, 1 row affected, 1 warning (0.01 sec) -
MySQL数据库时间类型指定精度时,插入时间零值会显示精度,GaussDB则不显示,例如: - GaussDB指定时间精度
gaussdb=# CREATE TABLE test(f1 TIME(3) NOT NULL, f2 DATETIME(3) NOT NULL, f3 TIMESTAMP(3) NOT NULL);
CREATE TABLE
gaussdb=# INSERT IGNORE INTO test VALUES(NULL,NULL,NULL);
WARNING: null value in column "f1" violates not-null constraint
DETAIL: Failing row contains (null, null, null).
WARNING: null value in column "f2" violates not-null constraint
DETAIL: Failing row contains (null, null, null).
WARNING: null value in column "f3" violates not-null constraint
DETAIL: Failing row contains (null, null, null).
INSERT 0 1
gaussdb=# SELECT * FROM test;
f1 | f2 | f3
----------+---------------------+---------------------
00:00:00 | 1970-01-01 00:00:00 | 1970-01-01 00:00:00
(1 row) -
MySQL指定时间精度 mysql> CREATE TABLE test(f1 TIME(3) NOT NULL, f2 DATETIME(3) NOT NULL, f3 TIMESTAMP(3) NOT NULL);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT IGNORE INTO test VALUES(NULL,NULL,NULL);
Query OK, 1 row affected, 3 warnings (0.00 sec)
mysql> SELECT * FROM test;
+--------------+-------------------------+-------------------------+
| f1 | f2 | f3 |
+--------------+-------------------------+-------------------------+
| 00:00:00.000 | 0000-00-00 00:00:00.000 | 0000-00-00 00:00:00.000 |
+--------------+-------------------------+-------------------------+
1 row in set (0.00 sec) - 由于MySQL数据库和GaussDB执行过程的差异,因此,产生的warnings条数可能不同,例如:
- GaussDB产生的warnings条数
gaussdb=# CREATE TABLE test(f1 INT, f2 INT not null);
CREATE TABLE
gaussdb=# INSERT INTO test VALUES(1,0),(3,0),(5,0);
INSERT 0 3
gaussdb=# INSERT IGNORE INTO test SELECT f1+1, f1/f2 FROM test;
WARNING: division by zero
CONTEXT: referenced column: f2
WARNING: null value in column "f2" violates not-null constraint
DETAIL: Failing row contains (2, null).
WARNING: division by zero
CONTEXT: referenced column: f2
WARNING: null value in column "f2" violates not-null constraint
DETAIL: Failing row contains (4, null).
WARNING: division by zero
CONTEXT: referenced column: f2
WARNING: null value in column "f2" violates not-null constraint
DETAIL: Failing row contains (6, null).
INSERT 0 3 - MySQL产生的warnings条数
mysql> CREATE TABLE test(f1 INT, f2 INT not null);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO test VALUES(1,0),(3,0),(5,0);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> INSERT IGNORE INTO test SELECT f1+1, f1/f2 FROM test;
Query OK, 3 rows affected, 4 warnings (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 4 -
MySQL数据库和GaussDB INSERT IGNORE在触发器中的差异,例如: - GaussDB触发器中使用INSERT IGNORE
gaussdb=# CREATE TABLE test1(f1 INT NOT NULL);
CREATE TABLE
gaussdb=# CREATE TABLE test2(f1 INT);
CREATE TABLE
gaussdb=# CREATE OR REPLACE FUNCTION trig_test() RETURNS TRIGGER AS $$
gaussdb$# BEGIN
gaussdb$# INSERT IGNORE INTO test1 VALUES(NULL);
gaussdb$# RETURN NEW;
gaussdb$# END;
gaussdb$# $$ LANGUAGE plpgsql;
CREATE FUNCTION
gaussdb=# CREATE TRIGGER trig2 BEFORE INSERT ON test2 FOR EACH ROW EXECUTE PROCEDURE trig_test();
CREATE TRIGGER
gaussdb=# INSERT INTO test2 VALUES(NULL);
WARNING: null value in column "f1" violates not-null constraint
DETAIL: Failing row contains (null).
CONTEXT: SQL statement "INSERT IGNORE INTO test1 VALUES(NULL)"
PL/pgSQL function trig_test() line 3 at SQL statement
INSERT 0 1
gaussdb=# SELECT * FROM test1;
f1
----
0
(1 rows)
gaussdb=# SELECT * FROM test2;
f1
----
(1 rows) -
MySQL触发器中使用INSERT IGNORE mysql> CREATE TABLE test1(f1 INT NOT NULL);
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE test2(f1 INT);
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ||
mysql> CREATE TRIGGER trig2 BEFORE INSERT ON test2 FOR EACH ROW
-> BEGIN
-> INSERT IGNORE into test1 values(NULL);
-> END||
Query OK, 0 rows affected (0.01 sec)
mysql> DELIMITER ;
mysql> INSERT INTO test2 VALUES(NULL);
ERROR 1048 (23000): Column 'f1' cannot be null
mysql> INSERT IGNORE INTO test2 VALUES(NULL);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM test1;
+----+
| f1 |
+----+
| 0 |
+----+
1 row in set (0.00 sec)
mysql> SELECT * FROM test2;
+------+
| f1 |
+------+
| NULL |
+------+
1 row in set (0.00 sec) -
GaussDB的bool、serial的实现机制与MySQL不同,因此其默认零值与MySQL不同,例如: - GaussDB的行为
gaussdb=# CREATE TABLE test(f1 SERIAL, f2 BOOL NOT NULL);
NOTICE: CREATE TABLE will create implicit sequence "test_f1_seq" for serial column "test.f1"
CREATE TABLE
gaussdb=# INSERT IGNORE INTO test values(NULL,NULL);
WARNING: null value in column "f1" violates not-null constraint
DETAIL: Failing row contains (null, null).
WARNING: null value in column "f2" violates not-null constraint
DETAIL: Failing row contains (null, null).
INSERT 0 1
gaussdb=# SELECT * FROM test;
f1 | f2
----+----
0 | f
(1 row) -
MySQL的行为 mysql> CREATE TABLE test(f1 SERIAL, f2 BOOL NOT NULL);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT IGNORE INTO test values(NULL,NULL);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> SELECT * FROM test;
+----+----+
| f1 | f2 |
+----+----+
| 1 | 0 |
+----+----+
1 row in set (0.00 sec) |