DML
概述 |
详细语法说明 |
差异 |
---|---|---|
DELETE支持从多个表中删除数据 |
DELETE |
|
UPDATE支持从多个表中更新数据 |
UPDATE |
在多表更新执行过程中,若发现将要更新的元组被其他会话并发修改,会取该条会话匹配中所有元组的最新值重新进行匹配,若依然满足条件再对这条元组进行更新。这个过程中MySQL对所有目标表的更新是一致的,而GaussDB仅会对涉及并发更新的目标表的元组进行重新匹配,可能产生数据不一致。 |
SELECT INTO语法 |
SELECT |
|
REPLACE INTO语法 |
REPLACE |
时间类型初始值的差异。例如:
|
LOAD DATA导入数据功能 |
LOAD DATA |
在使用LOAD DATA导入数据功能时,GaussDB与MySQL相比有如下差异:
|
LIMIT子句差异 |
DELETE、SELECT、UPDATE |
各个语句的limit子项与MySQL的limit项当前存在差异。 GaussDB中limit参数最大值为BIG INT类型限制(超过9223372036854775807报错)。在MySQL中,limit最大值为unsigned LONGLONG类型限制(超过18446744073709551615 报错)。 limit可以设置小数值,实际执行时四舍五入。MySQL不能取小数。 |
反斜杠(\)用法差异 |
INSERT |
反斜杠(\)的用法在GaussDB和MySQL中都可以由参数控制但当前默认用法不同: MySQL中使用参数NO_BACKSLASH_ESCAPES控制字符串和标识符中的反斜杠(\)被解析为普通字符还是转义字符,默认反斜杠字符(\)作为字符串和标识符中的转义字符。使用“SET sql_mode='NO_BACKSLASH_ESCAPES';”语句可以禁用反斜杠字符(\)作为字符串和标识符中的转义字符。 GaussDB中使用参数standard_conforming_strings控制字符串和标识符中的反斜杠(\)被解析为普通字符还是转义字符。默认值为on,在普通字符串文本中按照SQL标准把反斜杠(\)当普通文本。使用“SET standard_conforming_strings=off;”语句将反斜杠字符(\)作为字符串和标识符中的转义字符。 |
插入值少于字段数目时,MySQL报错,GaussDB补充空值 |
INSERT |
GaussDB不指定列的列表时,如果插入值少于字段数目,默认按建表时的字段顺序赋值。字段上有非空约束时报错,没有非空约束时,如果指定了默认值则缺省部分补充默认值,若未指定默认值则补充空。 |
ORDER BY中排序的列必须包括在结果集的列中 |
SELECT |
在GaussDB中,在与GROUP BY子句一起使用的情况下,ORDER BY中排序的列必须包括在SELECT语句所检索的结果集的列中。在与DISTINCT关键字一起使用的情况下,ORDER BY中排序的列必须包括在SELECT语句所检索的结果集的列中。 |
外键数据类型是timestamp/datetime时,UPDATE/DELETE外表报错 |
UPDATE/DELETE |
外键数据类型是timestamp/datetime时,UPDATE/DELETE外表报错,MySQL成功。 |
NATURAL JOIN语法 |
SELECT |
|
JOIN语法 |
SELECT |
GaussDB JOIN不支持使用逗号“,”的连接方式,MySQL支持。 GaussDB不支持USE INDEX FOR JOIN。 GaussDB中STRAIGHT_JOIN多表关联场景下生成的执行计划,与MySQL可能存在差异。 |
SELECT语句显示的列名 |
SELECT |
|
SELECT导出文件(into outfile) |
SELECT ... INTO OUFILE ... |
SELECT INTO OUTFILE语法,导出文件中FLOAT、DOUBLE、REAL类型的值显示精度和MySQL存在差异,不影响COPY导入和导入后的值。 |
SELECT/UPDATE/INSERT/REPLACE指定模式名、表名 |
SELECT/UPDATE/INSERT/REPLACE |
|
UPDATE SET执行顺序与MySQL存在差异 |
UPDATE ... SET |
MySQL中,UPDATE SET的顺序是从前往后依次UPDATE,前面UPDATE的结果会影响后面的结果,且允许多次设置同一列;GaussDB中为先取出原来的所有相关的数据,再一次性UPDATE,且不允许多次设置同一列,二者存在差异。设置GUC兼容性参数m_format_dev_version为's2'后,仅在单表场景可保持与MySQL行为一致,既支持同一列设置多次,且引用更新后的结果。 |
IGNORE特性 |
UPDATE/DELETE/INSERT |
MySQL数据库和GaussDB执行过程的差异,因此产生的WARNING条数和WARNING信息可能存在不同。 |
SHOW COLUMNS语法 |
SHOW |
|
SHOW CREATE DATABASE语法 |
SHOW |
用户权限验证与MySQL存在差异。
|
SHOW CREATE TABLE语法 |
SHOW |
|
SHOW CREATE VIEW语法 |
SHOW |
|
SHOW PROCESSLIST语法 |
SHOW |
GaussDB中该命令的查询结果中的字段内容和大小写与information_schema.processlist视图内字段内容与大小写保持一致,MySQL中可能存在差异。
|
SHOW [STORAGE] ENGINES |
SHOW |
GaussDB中该命令的查询结果中的字段内容和大小写与information_schema.engines视图内字段内容与大小写保持一致,MySQL中可能存在差异。因为MySQL与GaussDB的存储引擎不同,所以该指令查询的结果不同。 |
SHOW [SESSION] STATUS |
SHOW |
GaussDB中该命令的查询结果中的字段内容和大小写与information_schema.session_status视图内字段内容与大小写保持一致,MySQL中可能存在差异。GaussDB中当前仅支持Threads_connected和Uptime。 |
SHOW [GLOBAL] STATUS |
SHOW |
GaussDB中该命令的查询结果中的字段内容和大小写与information_schema.global_status视图内字段内容与大小写保持一致,MySQL中可能存在差异。GaussDB中当前仅支持Threads_connected和Uptime。 |
SHOW INDEX |
SHOW |
|
SHOW SESSION VARIABLES |
SHOW |
GaussDB中查询结果中字段内容及大小写与information_schema.session_variables视图内字段内容及大小写保持一致,与MySQL可能存在差异。 GaussDB中对查询结果中字段使用LIKE和WHERE进行选择时,排序规则与information_schema.session_variables视图内对应字段保持一致。 |
SHOW GLOBAL VARIABLES |
SHOW |
GaussDB中查询结果中字段内容及大小写与information_schema.global_variables视图内字段内容及大小写保持一致,与MySQL可能存在差异。 GaussDB中对查询结果中字段使用LIKE和WHERE进行选择时,排序规则与information_schema.global_variables视图内对应字段保持一致。 |
SHOW CHARACTER SET |
SHOW |
GaussDB中查询结果中字段内容及大小写与information_schema.character_sets视图内字段内容及大小写保持一致,与MySQL可能存在差异。 GaussDB中对查询结果中字段使用LIKE和WHERE进行选择时,排序规则与information_schema.character_sets视图内对应字段保持一致。 |
SHOW COLLATION |
SHOW |
GaussDB中查询结果中字段内容及大小写与information_schema.collations视图内字段内容及大小写保持一致,与MySQL可能存在差异。 GaussDB中对查询结果中字段使用LIKE和WHERE进行选择时,排序规则与information_schema.collations视图内对应字段保持一致。 |
SHOW TABLES |
SHOW |
|
SHOW TABLE STATUS |
SHOW |
|
SHOW DATABASES |
SHOW |
GaussDB中:查询结果中字段使用字符集utf8mb4、字符序utf8mb4_bin。 |
支持SQL_MODE中ONLY_FULL_GROUP_BY选项 |
SELECT |
SELECT列表中非聚合函数列与GROUP BY字段不一致时,非聚合函数列都需要出现GROUP BY列表或WHERE列表中,且WHERE子句中的列需要等于某一常量时,不报错。其中WHERE子句中的列,GaussDB支持入参数为1的函数列表达式,MySQL不支持函数列表达式。 GaussDB只支持GROUP BY后字段为正整数。 |
使用SELECT查询系统参数、用户变量 |
SELECT @variable、SELECT @@variable |
|
子查询 |
SELECT |
|
SELECT后跟行表达式 |
SELECT |
MySQL不支持SELECT后跟行表达式,GaussDB支持SELECT后跟行表达式。 MySQL的行为: mysql> SELECT row(1,2); ERROR 1241 (21000): Operand should contain 1 column(s) GaussDB的行为: m_db=# SELECT row(1,2); row(1,2) ---------- (1,2) (1 row) |
SELECT视图查询、子查询或UNION涉及NUMERIC转TIME/DATETIME进位差异 |
SELECT |
SELECT部分场景下输出TIME/DATETIME类型结果与MySQL存在差异。 差异场景:视图查询、子查询或UNION;涉及NUMERIC转TIME/DATETIME。 差异行为:GaussDB的SELECT行为统一,NUMERIC转TIME/DATETIME类型时,只对最大精度位(6)作进位处理。MySQL的视图查询、子查询和UNION场景,对实际的结果精度位作进位处理。 MySQL的行为: -- 简单查询,只对最大精度位6作进位,所以输出11:11:00.00002。 mysql> SELECT maketime(11, 11, 2.2/time '08:30:23.01'); +------------------------------------------+ | maketime(11, 11, 2.2/time '08:30:23.01') | +------------------------------------------+ | 11:11:00.00002 | +------------------------------------------+ 1 row in set (0.01 sec) -- 子查询,对实际的结果精度位作进位,所以输出11:11:00.00003。 mysql> SELECT * FROM (SELECT maketime(11, 11, 2.2/time '08:30:23.01')) f1; +------------------------------------------+ | maketime(11, 11, 2.2/time '08:30:23.01') | +------------------------------------------+ | 11:11:00.00003 | +------------------------------------------+ 1 row in set (0.00 sec) GaussDB的行为: m_db=# SET m_format_behavior_compat_options= 'enable_precision_decimal'; SET -- 简单查询,只对最大精度位6作进位,所以输出11:11:00.00002。 m_db=# SELECT maketime(11, 11, 2.2/time '08:30:23.01'); maketime ---------------- 11:11:00.00002 (1 row) -- 子查询,也只对最大精度位6作进位,结果精度是5,所以输出。11:11:00.00002 m_db=# SELECT * FROM (SELECT maketime(11, 11, 2.2/time '08:30:23.01')) f1; maketime ---------------- 11:11:00.00002 (1 row) |
SELECT在数值类型和子查询日期与时间函数的运算处理差异 |
SELECT |
SELECT在数值类型和子查询日期与时间函数的运算场景,GUC参数m_format_behavior_compat_options开启enable_precision_decimal选项,GaussDB会先将函数返回的日期与时间转换为数值类型,然后按照数值类型运算,结果也为数值类型。MySQL在子查询条件查询、分组查询等场景会截断日期与时间函数返回值。 MySQL的行为: mysql> SELECT 1.5688 * (SELECT adddate('2020-10-20', interval 1 day) WHERE true GROUP BY 1 HAVING true); +--------------------------------------------------------------------------------+ | 1.5688 * (SELECT adddate('2020-10-20', interval 1 day) WHERE true HAVING true) | +--------------------------------------------------------------------------------+ | 3168.976 | GaussDB的行为: m_db=# SELECT 1.5688 * (SELECT adddate('2020-10-20', interval 1 day) WHERE true GROUP BY 1 HAVING true); ?column? -------------------- 31691361.744799998 (1 row) |
SELECT在嵌套子查询时unsigned类型差异 |
SELECT |
SELECT在嵌套子查询时unsigned类型不会被覆盖,与MySQL 5.7存在差异。 MySQL 5.7的行为: mysql> DROP TABLE IF EXISTS t1; Query OK, 0 rows affected (0.02 sec) mysql> CREATE TABLE t1 ( -> c10 real(10, 4) zerofill -> ); Query OK, 0 rows affected (0.03 sec) mysql> INSERT INTO t1 VALUES(123.45); Query OK, 1 row affected (0.00 sec) mysql> DESC t1; +-------+--------------------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------------------------+------+-----+---------+-------+ | c10 | double(10,4) unsigned zerofill | YES | | NULL | | +-------+--------------------------------+------+-----+---------+-------+ 1 row in set (0.01 sec) mysql> CREATE TABLE t1_sub_1 AS SELECT (SELECT * FROM t1); Query OK, 1 row affected (0.03 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> DESC t1_sub_1; +--------------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------------+--------------+------+-----+---------+-------+ | (SELECT * FROM t1) | double(10,4) | YES | | NULL | | +--------------------+--------------+------+-----+---------+-------+ 1 row in set (0.00 sec) GaussDB的行为: test=# DROP TABLE IF EXISTS t1; DROP TABLE test=# CREATE TABLE t1 ( test(# c10 real(10, 4) ZEROFILL test(# ); CREATE TABLE test=# INSERT INTO t1 VALUES(123.45); INSERT 0 1 test=# DESC t1; Field | Type | Null | Key | Default | Extra -------+--------------------------------+------+-----+---------+------- c10 | double(10,4) unsigned zerofill | YES | | | (1 row) test=# CREATE TABLE t1_sub_1 AS SELECT (SELECT * FROM t1); INSERT 0 1 test=# DESC t1_sub_1; Field | Type | Null | Key | Default | Extra -------+-----------------------+------+-----+---------+------- c10 | double(10,4) unsigned | YES | | | (1 row) |
SELECT FOR SHARE/FOR UPDATE/LOCK IN SHARE MODE |
SELECT |
|
SELECT语法支持范围 |
SELECT |
|
不携带ORDER BY子句的UNION、GROUP BY等语句在数据合并或聚合的时候,由于使用执行器算子存在差异,不保证输出数据顺序和MySQL顺序一致。 |
SELECT |
以GROUP BY场景为例,使用hashagg算子时和原始顺序不同,建议需要保证数据顺序的场景添加ORDER BY子句。 -- 数据初始化 DROP TABLE IF EXISTS test; CREATE TABLE test(id INT); INSERT INTO test VALUES (1),(2),(3),(4),(5); -- GaussDB -- 不开精度传递,id顺序为(1 3 2 4 5) m_db=# SET m_format_behavior_compat_options= ''; SET m_db=# SELECT /*+ use_hash_agg*/ id, pi() FROM test GROUP BY 1,2; id | pi ----+------------------- 1 | 3.141592653589793 3 | 3.141592653589793 2 | 3.141592653589793 4 | 3.141592653589793 5 | 3.141592653589793 (5 rows) -- 打开精度传递,由于值变化导致顺序变化,id顺序为(5 4 2 3 1) m_db=# SET m_format_behavior_compat_options= 'enable_precision_decimal'; SET m_db=# SELECT /*+ use_hash_agg*/ id, pi() FROM test GROUP BY 1,2; id | pi ----+---------- 5 | 3.141593 4 | 3.141593 2 | 3.141593 3 | 3.141593 1 | 3.141593 (5 rows) -- MySQL,id顺序为原始顺序 mysql> SELECT id, pi() FROM test GROUP BY 1,2; +------+----------+ | id | pi() | +------+----------+ | 1 | 3.141593 | | 2 | 3.141593 | | 3 | 3.141593 | | 4 | 3.141593 | | 5 | 3.141593 | +------+----------+ 5 rows in set (0.00 sec) |
支持WITH AS语句 |
SELECT UPDATE DELETE |
|
INSERT ... ON DUPLICATE KEY UPDATE语法 |
INSERT |
m_db=# CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(10)); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t1_pkey" for table "t1" CREATE TABLE m_db=# INSERT INTO t1 values(1, 'A'); INSERT 0 1 m_db=# INSERT INTO t1 VALUES(1, 'X') ON DUPLICATE KEY UPDATE b=values(a)+values(b); ERROR: The double value 'X' is incorrect. CONTEXT: referenced column: b m_db=# INSERT INTO t1 VALUES(1, 'YY') ON DUPLICATE KEY UPDATE b=values(a)+values(b); ERROR: The double value 'YY' is incorrect. CONTEXT: referenced column: b m_db=# INSERT INTO t1 VALUES(1, 'ZZZ') ON DUPLICATE KEY UPDATE b=values(a)+values(b); ERROR: The double value 'ZZZ' is incorrect. CONTEXT: referenced column: b m_db=# DROP TABLE t1; DROP TABLE mysql> CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(10)); Query OK, 0 rows affected (0.00 sec) mysql> TRUNCATE TABLE t1; Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO t1 values(1, 'A'); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO t1 VALUES(1, 'X') ON DUPLICATE KEY UPDATE b=values(a)+values(b); ERROR 1292 (22007): Truncated incorrect DOUBLE value: 'X' mysql> INSERT INTO t1 VALUES(1, 'YY') ON DUPLICATE KEY UPDATE b=values(a)+values(b); Query OK, 2 rows affected, 2 warnings (0.00 sec) mysql> INSERT INTO t1 VALUES(1, 'ZZZ') ON DUPLICATE KEY UPDATE b=values(a)+values(b); ERROR 1292 (22007): Truncated incorrect DOUBLE value: 'ZZZ' mysql> DROP TABLE t1; Query OK, 0 rows affected (0.00 sec) |