1.3.3.6. 其他
1.3.3.6.1. GaussDB-Oracle
1.3.3.6.1.1. 权限加载生效
语法
FLUSH PRIVILEGES
警告
受配置参数控制,config/unisql.conf中unisql.global.replace.sql参数可配置需要替换的sql语句。
示例
-- 转换前MySQL SQL:
FLUSH PRIVILEGES;
-- 转换后GaussDB-Oracle SQL(unisql.global.replace.sql = 'select 1'):
SELECT 1;
1.3.3.6.1.2. 双竖线运算符
语法
双竖线(||)表示逻辑或运算
示例
-- 转换前MySQL SQL:
select 1 || -1;
INSERT INTO `tb_user_api_key` SELECT MD5(id) instance_id,id user_id,login_name user_name,
CASE WHEN (ISNULL(auth_password) = 1 ) || (LENGTH( trim(auth_password)) = 0 ) THEN MD5(id)
ELSE auth_password END api_key,TRUE STATUS;
-- 转换后GaussDB-Oracle SQL:
SELECT 1 OR -1;
INSERT INTO tb_user_api_key SELECT MD5(id) AS instance_id,id AS user_id,login_name AS user_name,
CASE WHEN (unisql.ISNULL(auth_password)=1) OR (LENGTH(trim(auth_password))=0) THEN MD5(id)
ELSE auth_password END AS api_key,TRUE AS STATUS;
警告
双竖线(||)表示逻辑或运算,表达式两侧需要使用括号包裹
1.3.3.6.1.3. 条件注释
语法
支持mysql/*!版本号 xxx*/ 条件注释语法,该情况仅语法实现,无实际功能;
仅支持/**/注释为独立一行存在,不包括嵌在其他sql语句中情况。
示例
-- 转换前MySQL SQL:
/*!40101 SET NAMES utf8 */
create table t1(id int primary key, name varchar(20), age text);
/*!40101 SET SQL_MODE=''*/alter table t1 add column sex varchar(10);
-- 转换后GaussDB-Oracle SQL:
CREATE TABLE t1 (id int PRIMARY KEY,name nvarchar2(20),age text);
ALTER TABLE t1 ADD sex nvarchar2(10);
1.3.3.6.1.4. 反单引号
语法
警告
支持mysql反单引号语法,默认将反单引号剔除。可通过配置文件参数(unisql.keyword.doublequotes)进行配置, 对象名如果匹配到了此配置参数中配置的关键字则使用双引号包裹,每个关键字之间用逗号分隔, 例如:unisql.keyword.doublequotes = name, age 表示name和age使用双引号包裹。
示例
-- 转换前MySQL SQL:
selecttb.`name`,tb.`instance_id`,e.`dest_instance_id`,e.`source_instance_id`
from tb_ci_concrete_collection e left join tb_ci_base_object tb on tb.instance_id = e.instance_id;
-- 转换后GaussDB-Oracle SQL:
SELECT tb.NAME,tb.instance_id,e.dest_instance_id,e.source_instance_id
FROM tb_ci_concrete_collection AS e LEFT JOIN tb_ci_base_object AS tb ON tb.instance_id=e.instance_id;
-- 配置unisql.keyword.doublequotes=name,转换后GaussDB-Oracle SQL:
SELECT tb."NAME",tb.instance_id,e.dest_instance_id,e.source_instance_id
FROM tb_ci_concrete_collection AS e LEFT JOIN tb_ci_base_object AS tb ON tb.instance_id=e.instance_id;
1.3.3.6.1.5. 转义字符 \
语法
警告
将参数unisql.mysql.backslash.escapes设置为1,将支持mysql 反斜杠 \
转义字符,当前仅支持对于单引号和反斜杠的转义组合,即 \'
和 \\
情况。
示例
create table t1(id int primary key, configurl text);
-- 转换前MySQL SQL:
insert into t1 values(1, '\content\'jres\' 1.0 encoding \\\UTF8');
insert into t1 values(2, '{\\\"nodelocator-server\\\" nodeNo=\\\"0 \\\ />\\r\\n\\r\\n\\t<plugins>\\"jres.logFactory \\\" load-level=\acm>}');
-- 转换后GaussDB-Oracle SQL:
INSERT INTO t1 VALUES (1,'content''jres'' 1.0 encoding \UTF8');
INSERT INTO t1 VALUES (2,'{\"nodelocator-server\" nodeNo=\"0 \ />\r\n\r\n\t<plugins>\"jres.logFactory \" load-level=acm>}');
1.3.3.6.1.6. 查看当前库所有表
语法
SHOW TABLES
示例
-- 转换前MySQL SQL:
SHOW TABLES;
-- 转换后GaussDB-Oracle SQL:
SELECT tablename FROM pg_tables WHERE schemaname=current_schema();
1.3.3.6.1.7. 锁表语句
语法
LOCK TABLES tbl_name READ | WRITE
UNLOCK TABLES
警告
UNLOCK TABLES受配置参数控制,config/unisql.conf中unisql.replace.sql参数可配置需要替换的sql语句。 GaussDB-Oracle必须在显式事务中使用LOCK TABLES语句,并且UNLOCK TABLES在事务的最后。 READ锁只阻塞并发事务的insert/delete/update/select。 WRITE锁只阻塞并发事务的insert/delete/update。
示例
-- 转换前MySQL SQL:
LOCK TABLES products READ;
LOCK TABLES products WRITE;
UNLOCK TABLES;
-- 转换后GaussDB-Oracle SQL(unisql.replace.sql = 'select 1'):
LOCK TABLES products IN ACCESS SHARE MODE;
LOCK TABLES products IN ACCESS EXCLUSIVE MODE;
SELECT 1;
1.3.3.6.1.8. 查看当前分区信息
语法
支持查询INFORMATION_SCHEMA.PARTITIONS来获取分区表信息,支持字段table_schema|table_name|partition_name|partition_method|partition_description
警告
GaussDB-Oracle默认存的小写,mysql大小写均可配置,所以大小写有差异, 可能导致结果不一致,目前不处理,所以建议均小写
hash分区范围值有差异,GaussDB-Oracle partition_description字段有范围值,mysql partition_description字段值为null
partition_method可能不一致,如mysql在分区键为字符串时,partition_method为RANGE COLUMNS(也有为NULL场景), GaussDB-Oracle只为RANGE
partition_description单引号差异,GaussDB-Oracle均为不带单引号,mysql在分区键为字符串时带单引号
默认查询顺序可能不一致,建议加上order by
示例
-- 转换前MySQL SQL:
select partition_description,partition_name from information_schema.partitions where table_schema = s1 and table_name = t1;
-- 转换后GaussDB-Oracle SQL
select partition_description,partition_name from unisql.partitions where table_schema = s1 and table_name = t1;
1.3.3.6.2. OceanBase-Oracle
1.3.3.6.2.1. 切换数据库
语法
use dbname;
警告
数据库名不支持大小写敏感,特殊字符,反引号大小写敏感
示例
-- 转换前MySQL SQL:
use dbname;
-- 转换后OceanBase-Oracle SQL:
ALTER SESSION SET CURRENT_SCHEMA = dbname;
1.3.3.6.2.2. SHOW TABLES
语法
SHOW [FULL] TABLES [FROM db_name]
[WHERE expr]
警告
不支持LIKE ‘pattern’
where 只支持 =, in, like 三种表达式
默认返回的表名为大写(没有双引号),和mysql不同
返回的结果集字段名为 table_name, table_type, mysql 为tables_in_具体的dbname, table_type
示例
-- 转换前MySQL SQL:
SHOW TABLES;
SHOW FULL TABLES FROM TEST_DB;
SHOW TABLES FROM TEST_DB WHERE TABLES_IN_TEST_DB='test_t';
SHOW FULL TABLES FROM TEST_DB WHERE table_type='base table';
-- 转换后SQL:
SELECT OBJECT_NAME AS TABLE_NAME FROM ALL_OBJECTS WHERE OWNER=sys_context('USERENV', 'CURRENT_SCHEMA') AND (OBJECT_TYPE IN ('TABLE','VIEW','SEQUENCE')) ORDER BY TABLE_NAME
SELECT OBJECT_NAME AS TABLE_NAME,CASE WHEN OBJECT_TYPE='TABLE' THEN 'BASE TABLE' ELSE OBJECT_TYPE END AS TABLE_TYPE FROM ALL_OBJECTS WHERE OWNER='TEST_DB' AND (OBJECT_TYPE IN ('TABLE','VIEW','SEQUENCE')) ORDER BY TABLE_NAME
SELECT OBJECT_NAME AS TABLE_NAME FROM ALL_OBJECTS WHERE OWNER='TEST_DB' AND (OBJECT_TYPE IN ('TABLE','VIEW','SEQUENCE')) AND (OBJECT_NAME='TEST_T') ORDER BY TABLE_NAME
SELECT OBJECT_NAME AS TABLE_NAME,CASE WHEN OBJECT_TYPE='TABLE' THEN 'BASE TABLE' ELSE OBJECT_TYPE END AS TABLE_TYPE FROM ALL_OBJECTS WHERE OWNER='TEST_DB' AND (OBJECT_TYPE IN ('TABLE','VIEW','SEQUENCE')) AND (OBJECT_TYPE='TABLE') ORDER BY TABLE_NAME
1.3.3.6.2.3. 查看当前分区信息
语法
支持查询INFORMATION_SCHEMA.PARTITIONS来获取分区表信息,支持字段table_schema|table_name|partition_name|partition_description
警告
oceanbase-oracle默认存的大写,mysql大小写均可配置,所以大小写有差异, 可能导致结果不一致,目前不处理,所以建议均大写
默认查询顺序可能不一致,建议加上order by
示例
-- 转换前MySQL SQL:
select partition_description,partition_name from information_schema.partitions where table_schema = 'SCHEMA1' and table_name = 'TABLE1';
-- 转换后Oceanbase-Oracle SQL
SELECT partition_description,partition_name FROM unisql.partitions WHERE table_schema='SCHEMA1' AND table_name='TABLE1'
1.3.3.6.2.4. 查看表索引信息
语法
支持查询INFORMATION_SCHEMA.statistics来获取表索引信息,支持字段table_schema|table_name
警告
oceanbase-oracle默认存的大写,mysql大小写均可配置,所以大小写有差异, 可能导致结果不一致,目前不处理,所以建议均大写
默认查询顺序可能不一致,建议加上order by
示例
-- 转换前MySQL SQL:
SELECT COUNT(*) AS index_count FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 'TEST_STATISTICS_1';
-- 转换后Oceanbase-Oracle SQL
SELECT COUNT(1) AS index_count FROM unisql.STATISTICS WHERE TABLE_NAME='TEST_STATISTICS_1'
1.3.3.6.2.5. 查看表约束信息
语法
支持查询INFORMATION_SCHEMA.key_column_usage来获取表约束信息,支持字段constraint_schema|table_schema|table_name|constraint_name|column_name|ordinal_position
警告
oceanbase-oracle默认存的大写,mysql大小写均可配置,所以大小写有差异, 可能导致结果不一致,目前不处理,所以建议均大写
主键约束和mysql保持一致映射成 PRIMARY
视图目前只查询了主键约束和唯一约束
默认查询顺序可能不一致,建议加上order by
示例
-- 转换前MySQL SQL:
SELECT column_name FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE constraint_schema = 'SCHEMA1' and TABLE_NAME = 'TEST_KEY_USAGE_1' and constraint_name = 'PRIMARY';
-- 转换后Oceanbase-Oracle SQL
SELECT column_name FROM unisql.KEY_COLUMN_USAGE WHERE constraint_schema='SCHEMA1' AND TABLE_NAME='TEST_KEY_USAGE_1' AND constraint_name='PRIMARY'
1.3.3.6.3. GaussDB-Mysql
1.3.3.6.3.1. 查看当前库所有表名
语法
SHOW TABLES
警告
对于gaussdb-mysql 505.2 此版本已支持该语法(需要设置unisql.target.database.version = 5050200)
GaussDB-Mysql B 模式,关于如何确认目标库是否为 B 模式,具体参考:修改索引名称,源库查询针对数据库级别下所有表名查询,而GaussDB-Mysql B 模式转化后针对模式级别下所有表名查询
示例
-- 转换前MySQL SQL:
SHOW TABLES;
-- 转换后GaussDB-Mysql SQL:
-- 配置项:unisql.target.database.version = 5050200
SHOW TABLES
-- 转换后GaussDB-Mysql B 模式 SQL:
SELECT `tablename` FROM `pg_tables` WHERE `schemaname`=current_schema();
1.3.3.6.3.2. 锁表语句
语法
LOCK TABLES tbl_name READ
警告
GaussDB-Mysql B模式必须在显式事务中使用锁表语句,M模式不支持。
当前仅支持锁定单个表,锁类型仅支持 READ。
示例
-- 转换前MySQL SQL:
LOCK TABLES products READ;
-- 转换后GaussDB-Mysql B 模式 SQL:
LOCK TABLES products IN ACCESS SHARE MODE;
1.3.3.6.3.3. 权限加载生效
语法
FLUSH PRIVILEGES
警告
受配置参数控制,config/unisql.conf中unisql.global.replace.sql参数可配置需要替换的sql语句。
示例
-- 转换前MySQL SQL:
FLUSH PRIVILEGES;
-- 转换后 SQL(unisql.global.replace.sql = 'select 1'):
SELECT 1;
1.3.3.6.3.4. 查看当前分区信息
语法
支持查询INFORMATION_SCHEMA.PARTITIONS来获取分区表信息,支持字段table_schema|table_name|partition_name|partition_method|partition_description
警告
mysql大小写均可配置,统一SQL转换时统一按照小写进行处理,查询时系统表名建议使用小写
partition_description单引号差异,GaussDB-MySQL均为不带单引号,mysql在分区键为字符串时带单引号
默认查询顺序可能不一致,建议加上order by
list分区、hash分区、range分区中分区时仅支持指定分区列名,不支持在分区列名上嵌套函数,如不支持 CREATE TABLE logs_250623 (id INT, user_id INT) PARTITION BY HASH (MOD(user_id, 10)) PARTITIONS 4 中的 MOD(user_id, 10);
hash分区范围值有差异,GaussDB-mysql partition_description字段有范围值,mysql partition_description字段值为null
示例
-- 转换前MySQL SQL:
SELECT MAX(partition_description) as max_value FROM INFORMATION_SCHEMA.PARTITIONS WHERE table_schema='acm' AND table_name='hash_num_250623_34513';
-- 转换后GaussDB-MySQL SQL
SELECT MAX(`partition_description`) AS `max_value` FROM `unisql`.`partitions` WHERE `table_schema`='acm' AND `table_name`='hash_num_250623_34513';
1.3.3.6.3.5. 关键字作为表名和列名
语法
如果使用的表名和列名在统一SQL中不支持,是因为使用到了统一SQL解析器的关键字。可以通过将关键字加入配置参数unisql.keyword.doublequotes,例如:unisql.keyword.doublequotes = order,key。这样将关键字作为普通字符串处理。
示例
EXEC SET unisql.keyword.doublequotes = order
-- 转换前MySQL SQL:
-- 使用order作为表别名
SELECT t.`order`, t.`id` FROM tb_keyword_test AS t order by t.`order`;
-- 转换后GaussDB-MySQL SQL
SELECT `t`."order",`t`.`id` FROM `tb_keyword_test` AS `t` ORDER BY `t`."order";
1.3.3.6.4. DM
1.3.3.6.4.1. 转义字符 \
语法
警告
将参数unisql.mysql.backslash.escapes设置为1,将支持mysql 反斜杠
\
转义字符,当前仅支持对于单引号和反斜杠的转义组合,即\'
和\\
情况。- 在DM中like中反斜杠只能匹配
\
,_
,%
。后面不能跟普通字符,执行会报错。 因此如下SQL执行会报错:
select * from t1 where key1 like '\\abc'
, 会转换为select * from t1 where key1 like '\abc' ESCAPE '\'
- 在DM中like中反斜杠只能匹配
示例
create table t1(id int primary key, configurl text);
-- 转换前MySQL SQL:
insert into t1 values(1, '\content\'jres\' 1.0 encoding \\\UTF8');
insert into t1 values(2, '{\\\"nodelocator-server\\\" nodeNo=\\\"0 \\\ />\\r\\n\\r\\n\\t<plugins>\\"jres.logFactory \\\" load-level=\acm>}');
select * from t1 where configurl like '{\\\\\"nodel%';
-- 转换后 SQL:
INSERT INTO t1 VALUES (1,'content''jres'' 1.0 encoding \UTF8');
INSERT INTO t1 VALUES (2,'{\"nodelocator-server\" nodeNo=\"0 \ />\r\n\r\n\t<plugins>\"jres.logFactory \" load-level=acm>}');
SELECT * FROM t1_c WHERE configurl LIKE '{\\"nodel%' ESCAPE '\'
1.3.3.6.4.2. 查看当前分区信息
语法
支持查询INFORMATION_SCHEMA.PARTITIONS来获取分区表信息,支持字段table_schema|table_name|partition_name|partition_method|partition_description
警告
MySQL 查询时表字段显示为小写;dm 字段显示为大写
MySQL 字段值显示为小写;DM 字段值显示为大写
DM partition_method 不支持值为 RANGE COLUMNS,LIST COLUMNS ,仅支持 RANGE, LIST
DM where 条件单引号包裹的值的大小写由数据库中存储的大小写决定,建议全大写
MySQL partition_name字段值显示成 p + 序号的格式;DM partition_name字段值显示成 DMHASHPART + 序号的格式
默认查询顺序可能不一致,需要加上 order by
示例
-- 转换前MySQL SQL:
select partition_description,partition_name from information_schema.partitions where table_schema = 'S1' and table_name = 'T1';
-- 转换后DM SQL
select partition_description,partition_name from unisql.partitions where table_schema = 'S1' and table_name = 'T1';
1.3.3.6.4.3. SHOW TABLES
语法
SHOW [FULL] TABLES [FROM db_name]
[WHERE expr]
警告
不支持LIKE ‘pattern’
where 只支持 =, in, like 三种表达式
默认返回的表名为大写(没有双引号),和mysql不同
返回的结果集字段名为 table_name, table_type, mysql 为tables_in_具体的dbname, table_type
示例
-- 转换前MySQL SQL:
SHOW TABLES;
SHOW FULL TABLES FROM TEST_DB;
SHOW TABLES FROM TEST_DB WHERE TABLES_IN_TEST_DB='test_t';
SHOW FULL TABLES FROM TEST_DB WHERE table_type='base table';
-- 转换后SQL:
SELECT OBJECT_NAME AS TABLE_NAME FROM ALL_OBJECTS WHERE OWNER=sys_context('USERENV', 'CURRENT_SCHEMA') AND (OBJECT_TYPE IN ('TABLE','VIEW','SEQUENCE')) ORDER BY TABLE_NAME
SELECT OBJECT_NAME AS TABLE_NAME,CASE WHEN OBJECT_TYPE='TABLE' THEN 'BASE TABLE' ELSE OBJECT_TYPE END AS TABLE_TYPE FROM ALL_OBJECTS WHERE OWNER='TEST_DB' AND (OBJECT_TYPE IN ('TABLE','VIEW','SEQUENCE')) ORDER BY TABLE_NAME
SELECT OBJECT_NAME AS TABLE_NAME FROM ALL_OBJECTS WHERE OWNER='TEST_DB' AND (OBJECT_TYPE IN ('TABLE','VIEW','SEQUENCE')) AND (OBJECT_NAME='TEST_T') ORDER BY TABLE_NAME
SELECT OBJECT_NAME AS TABLE_NAME,CASE WHEN OBJECT_TYPE='TABLE' THEN 'BASE TABLE' ELSE OBJECT_TYPE END AS TABLE_TYPE FROM ALL_OBJECTS WHERE OWNER='TEST_DB' AND (OBJECT_TYPE IN ('TABLE','VIEW','SEQUENCE')) AND (OBJECT_TYPE='TABLE') ORDER BY TABLE_NAME
1.3.3.6.4.4. 转换clob 类型字段和绑定参数的=操作和in操作
语法
支持在select, update, delete 中进行转换 会对下述三种情况进行转换(col为clob 类型):
col = ?
? = col
col in (?,?)
警告
若没有元数据,则不转换
若字段没有指定表名(或指定的表名不代表实际表,如为子查询别名或CTE),且字段名在多个表中都存在,但类型不同,也不转换
若SQL中多个表有相同的别名(位于不同查询块),且字段在这些表中都存在,且类型不同,可能会对非clob类型的字段进行转换
示例
CREATE TABLE test_clob_param (
id INT PRIMARY KEY,
val text NOT NULL
);
-- 转换前MySQL SQL:
SELECT * FROM test_clob_param WHERE val=?;
SELECT * FROM test_clob_param WHERE ?=val;
SELECT * FROM test_clob_param WHERE val in (§{abcd, varchar}, 'qw', §{abcde, varchar})
-- 转换后 SQL:
SELECT * FROM test_clob_param WHERE dbms_lob.compare(val, to_clob(?))=0;
SELECT * FROM test_clob_param WHERE dbms_lob.compare(val, to_clob(?))=0;
SELECT * FROM test_clob_param WHERE ((dbms_lob.compare(val, to_clob(?))=0) OR (val='qw') OR (dbms_lob.compare(val, to_clob(?))=0));