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.2.6. 权限加载生效
语法
FLUSH PRIVILEGES
警告
受配置参数控制,config/unisql.conf中unisql.global.replace.sql参数可配置需要替换的sql语句。 unisql.conf文件说明。
目标数据库没有此功能,尽量配置成无实际功能的目标端可执行SQL语句。
示例
-- 转换前MySQL SQL:
FLUSH PRIVILEGES;
-- 转换后Oceanbase-Oracle SQL(unisql.global.replace.sql = 'select 1'):
SELECT 1;
1.3.3.6.2.7. 支持查询条件中指定表字段是否按大小写敏感查询
语法
在select, with, insert语句中支持大小写不敏感
示例
-- 配置大小写不敏感的表字段类型
EXEC SET unisql.table.column.upper.case = table_upper_case:nosensitive_id;
EXEC SET unisql.table.column.upper.case.print.sql.switch = 1
-- 创建表并插入数据
CREATE TABLE table_upper_case (
id INT PRIMARY KEY,
sensitive_name VARCHAR(20),
nosensitive_id VARCHAR(20)
);
INSERT INTO table_upper_case VALUES
(1, 'Alice', 'Alice101'),
(2, 'Bob', 'Bob102'),
(3, 'Charlie', 'Charlie103'),
(4, 'Jack', 'Jack104');
CREATE TABLE table_email_upper (
sensitive_name VARCHAR(20),
sensitive_email VARCHAR(20)
);
INSERT INTO table_email_upper VALUES
('Alice', 'Alice@gmail.com'),
('Bob', 'Bob@gmail.com'),
('Charlie', 'Charlie@gmail.com'),
('Jack', 'Jack@gmail.com');
-- 转换前MySQL SQL:
SELECT id FROM table_upper_case WHERE nosensitive_id = 'Bob102' ORDER BY id;
WITH cte AS (
SELECT sensitive_name,id
FROM table_upper_case
WHERE nosensitive_id = 'Bob102'
LIMIT 1
)
SELECT cte.id
FROM table_email_upper AS a
INNER JOIN cte ON a.sensitive_name = cte.sensitive_name;
-- 转换后 SQL:
SELECT id FROM table_upper_case WHERE upper(nosensitive_id)=upper('Bob102') ORDER BY id;
WITH cte AS (SELECT sensitive_name,id FROM table_upper_case WHERE upper(nosensitive_id)=upper('Bob102') FETCH NEXT 1 ROWS ONLY ) SELECT cte.id FROM table_email_upper a INNER JOIN cte ON a.sensitive_name=cte.sensitive_name;
1.3.3.6.2.8. 转换clob 类型字段的比较操作符(=,!=, in, not in)
说明
oceanbase-oracle 不支持clob 类型字段的比较操作符(=,!=, in, not in),所以需要转换。
语法
支持在select, update, delete 中进行转换。 会对下述情况进行转换(col为clob 类型):
col = expr
expr = col
col in (expr,expr)
col != expr
expr != col
col not in (expr,expr)
警告
通过参数unisql.transform.clob.expr (unisql.conf文件说明)控制是否转换,默认值为0(不转换)
clob 类型字段的比较操作符(=,!=, in, not in)会被转换为dbms_lob.compare函数调用
若没有元数据,则不转换
示例
CREATE TABLE test_clob_param (
id INT PRIMARY KEY,
val text NOT NULL
);
-- 转换前MySQL SQL:
SELECT * FROM test_clob_param WHERE val='abcd';
SELECT * FROM test_clob_param WHERE val!='abcd';
SELECT * FROM test_clob_param WHERE 'abcd'=val;
SELECT * FROM test_clob_param WHERE val in ('abcd', 'qw', 'abcde')
SELECT * FROM test_clob_param WHERE val not in ('abcd', 'qw', 'abcde')
-- 转换后 SQL:
SELECT * FROM test_clob_param WHERE dbms_lob.compare(val, to_clob('abcd'))=0;
SELECT * FROM test_clob_param WHERE dbms_lob.compare(val, to_clob('abcd'))!=0;
SELECT * FROM test_clob_param WHERE dbms_lob.compare(val, to_clob('abcd'))=0;
SELECT * FROM test_clob_param WHERE ((dbms_lob.compare(val, to_clob('abcd'))=0) OR (dbms_lob.compare(val, to_clob('qw'))=0) OR (dbms_lob.compare(val, to_clob('abcde'))=0));
SELECT * FROM test_clob_param WHERE (dbms_lob.compare(val, to_clob('abcd'))!=0 AND dbms_lob.compare(val, to_clob('qw'))!=0 AND dbms_lob.compare(val, to_clob('abcde'))!=0);
1.3.3.6.2.9. 对查询列或GROUP BY中有clob字段且带有group by或distinct的语句进行转换
说明
对查询列或GROUP BY中有clob字段且带有group by或distinct的语句进行转换, 转换为子查询+row_number 窗口函数的形式
语法
会对下述情况进行转换(clob_col为clob 类型字段):
select [select_expr, ]clob_col[, select_expr] from table_references
[WHERE where_condition]
GROUP BY {col_name}, ...
[ORDER BY {col_name | expr} [ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
select distinct [select_expr, ]clob_col[, select_expr] from table_references
[WHERE where_condition]
[ORDER BY {col_name | expr} [ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
警告
依赖参数unisql.transform.clob.expr (unisql.conf文件说明)控制是否转换,默认值为0(不转换)
- 依赖元数据,targetlist 或group by中有clob类型字段 (只能为列表达式
select clob_col from t1这种)才这么转, 不然使用原方案 : concat(clob_col,'')这种非普通列不支持
- 依赖元数据,targetlist 或group by中有clob类型字段 (只能为列表达式
- 有distinct 或group by 才转,如果distinct 和group by 同时存在,不转换
select distinct sum(col1) as v1,sum(col3) as v2 , clob_col from t1 group by col2不支持
- 不支持having:
select sum(col1) as val, clob_col from t1 group by col2 having sum(col1) > 0不支持
- targetlist有通配符不转:
select * from t1 group by col1不支持
- 有窗口函数 over() 不转
select sum(col1) over(partition by col2 order by time) as val from t1 group by col3不支持
- targetlist 非字段表达式没有别名不转
select sum(col1) , clob_col from t1 group by col2不支持
- 不支持 order by 基于别名的表达式(直接使用别名可以),如:
select sum(col1) as val, clob_col from t1 group by col2 order by val+1不支持
当对clob 字段分组时,会套to_char 转为varchar2
order by 中不能有clob, 否则会执行报错
不使用UNISQL_ORDERBY_COL_FMT(
unisql_orderby_col_%d), UNISQL_ROWNUM(unisql_rownum) 作为字段别名或字段名
示例
CREATE TABLE clob_main_20251028_1 (
id INT PRIMARY KEY AUTO_INCREMENT,
clob_col TEXT,
int_col INT,
str_col VARCHAR(50),
dec_col DECIMAL(10,2),
dt_col DATE
);
-- 转换前MySQL SQL:
SELECT int_col, clob_col AS clob_alias, SUM(dec_col) AS sum_dec FROM clob_main_20251028_1 GROUP BY str_col ORDER BY sum_dec ASC;
SELECT DISTINCT str_col as str_alias, clob_col AS clob_alias FROM clob_main_20251028_1 ORDER BY int_col DESC;
-- 转换后 SQL:
SELECT int_col,clob_alias,sum_dec FROM (SELECT int_col,clob_col AS clob_alias,SUM(dec_col) OVER(PARTITION BY str_col) AS sum_dec,row_number() OVER (PARTITION BY str_col ORDER BY 1) AS unisql_rownum FROM clob_main_20251028_1) uni_sub WHERE unisql_rownum=1 ORDER BY sum_dec;
SELECT str_alias,clob_alias FROM (SELECT str_col AS str_alias,clob_col AS clob_alias,row_number() OVER (PARTITION BY str_col, to_char(clob_col) ORDER BY 1) AS unisql_rownum,int_col AS unisql_orderby_col_0 FROM clob_main_20251028_1) uni_sub WHERE unisql_rownum=1 ORDER BY unisql_orderby_col_0 DESC;
1.3.3.6.2.10. LIKE指定转义字符 \
语法 支持转义字符后跟随单引号,下划线,反斜杠,百分号。
警告
要求转义字符必须用于转义特殊字符。
将参数unisql.mysql.backslash.escapes设置为1,将支持mysql 反斜杠
\转义字符,当前仅支持对于单引号和反斜杠的转义组合,即\'和\\情况。只支持update,delete,select,show语句后where跟随的like语句中,不支持函数参数中的like语句中的转义字符。也不支持select查询对象like语句中的转义字符。
转义字符在字符串末尾不支持
转义字符后接单引号不支持,mysql用法与oceanbase-oracle不一致
示例
-- 转换前MySQL SQL:
create table t1(id int primary key, configurl text);
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%';
-- 支持普通字符反斜杠后跟随字符a
insert into t1 values(4, '\\\\a');
-- 不支持转义字符后跟随非转义特殊字符a
select * from t1 where configurl like '\\a';
- 转义字符在字符串末尾不支持
insert into test_backslash(val) values('abaa\\');
update test_backslash set val = 'Updated with' where val like 'abaa\\';
- 转义字符后接单引号不支持,mysql用法与oceanbase-oracle不一致
update test_backslash set val = 'Updated with' where val like 'ab\\\'aa'
-- 转换后 SQL:
CREATE TABLE t1 (id int PRIMARY KEY,configurl clob)
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%' ESCAPE '\'
-- 支持普通字符反斜杠后跟随字符a
INSERT INTO t1 VALUES (4,'\\a')
-- 不支持转义字符后跟随非转义特殊字符a,转换后的sql无法执行
SELECT * FROM t1 WHERE configurl LIKE '\a' ESCAPE '\'
- 转义字符在字符串末尾不支持,转换后无法执行
INSERT INTO test_backslash (val) VALUES ('abaa\')
UPDATE test_backslash SET val='Updated with' WHERE val LIKE 'abaa\' ESCAPE '\'
- 转义字符后接单引号不支持,mysql用法与oceanbase-oracle不一致
UPDATE test_backslash SET val='Updated with' WHERE val LIKE 'ab\''aa' ESCAPE '\'
1.3.3.6.2.11. union查询中存在clob 类型字段时union 转换为union all
说明
oceanbase-oracle 不支持clob 类型字段的union查询,转换成union all。
语法
支持在select … union查询中查询列中存在clob 类型字段。
[(]select column_clob[,column] from table1 [WHERE where_condition]
[GROUP BY {col_name | expr}][)]
UNION
[(]select column_clob[,column] from table2 [WHERE where_condition]
[GROUP BY {col_name | expr}][)]
[UNION...]
警告
通过参数unisql.transform.clob.union (unisql.conf文件说明)控制是否转换,默认值为0(不转换)
若没有元数据,则不转换
转换后两库数据会不一致(union all不会去重)请知悉
不支持函数参数中的union查询
不支持with cte
union的查询表不支持子查询(如上的语法中,table1和table2必须是具体表名,不能是子查询)
如果union 后是(select … from table)格式,()中的语法只能是单句的select 语法,不可以再有union
查询的列中 clob 类型字段,只能是明确的列名,不能作为函数入参,表达式组合。
union 外层只支持一层子查询:
select * from (select xxx from test_clob_param union select xxx from test_clob_param)在update、delete中通过该方法使用union 转成union all暂时无法解决字段不一致报错问题,请知悉
示例
-- 转换前MySQL SQL:
CREATE TABLE test_clob_union_1 (
id INT PRIMARY KEY,
val text NOT NULL
);
CREATE TABLE test_clob_union_2 (
id INT PRIMARY KEY,
val text NOT NULL
);
SELECT * FROM (select id,val from test_clob_union_1 union select id,val from test_clob_union_2) t WHERE t.id>0;
-- 转换后 SQL:
CREATE TABLE test_clob_union_1 (id int PRIMARY KEY,val clob NOT NULL);
CREATE TABLE test_clob_union_2 (id int PRIMARY KEY,val clob NOT NULL);
SELECT * FROM (SELECT id,val FROM test_clob_union_1 UNION ALL SELECT id,val FROM test_clob_union_2) t WHERE t.id>0
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. 查看表索引信息
语法
支持查询INFORMATION_SCHEMA.statistics来获取表索引信息,支持字段table_schema|table_name
警告
dm默认存的大写,mysql大小写均可配置,所以大小写有差异
默认查询顺序可能不一致,建议加上order by
示例
-- 转换前MySQL SQL:
SELECT COUNT(*) AS index_count FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 'TEST_STATISTICS_1';
-- 转换后DM SQL
SELECT COUNT(1) AS index_count FROM unisql.STATISTICS WHERE TABLE_NAME='TEST_STATISTICS_1'
1.3.3.6.4.4. 查看表约束信息
语法
支持查询INFORMATION_SCHEMA.key_column_usage来获取表约束信息,支持字段constraint_schema|constraint_name|table_schema|table_name|column_name|ordinal_position
警告
dm默认存的大写,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';
-- 转换后DM
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.4.5. 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.6. 转换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 (?, 'qw', ?)
-- 转换后 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));
1.3.3.6.4.7. 支持查询条件中指定表字段是否按大小写敏感查询
语法
在select, with, insert语句中支持大小写不敏感
示例
-- 配置大小写不敏感的表字段类型
EXEC SET unisql.table.column.upper.case = table_upper_case:nosensitive_id;
EXEC SET unisql.table.column.upper.case.print.sql.switch = 1
-- 创建表并插入数据
CREATE TABLE table_upper_case (
id INT PRIMARY KEY,
sensitive_name VARCHAR(20),
nosensitive_id VARCHAR(20)
);
INSERT INTO table_upper_case VALUES
(1, 'Alice', 'Alice101'),
(2, 'Bob', 'Bob102'),
(3, 'Charlie', 'Charlie103'),
(4, 'Jack', 'Jack104');
CREATE TABLE table_email_upper (
sensitive_name VARCHAR(20),
sensitive_email VARCHAR(20)
);
INSERT INTO table_email_upper VALUES
('Alice', 'Alice@gmail.com'),
('Bob', 'Bob@gmail.com'),
('Charlie', 'Charlie@gmail.com'),
('Jack', 'Jack@gmail.com');
-- 转换前MySQL SQL:
SELECT id FROM table_upper_case WHERE nosensitive_id = 'Bob102' ORDER BY id;
WITH cte AS (
SELECT sensitive_name,id
FROM table_upper_case
WHERE nosensitive_id = 'Bob102'
LIMIT 1
)
SELECT cte.id
FROM table_email_upper AS a
INNER JOIN cte ON a.sensitive_name = cte.sensitive_name;
-- 转换后 SQL:
SELECT id FROM table_upper_case WHERE upper(nosensitive_id)=upper('Bob102') ORDER BY id;
WITH cte AS (SELECT sensitive_name,id FROM table_upper_case WHERE upper(nosensitive_id)=upper('Bob102') FETCH NEXT 1 ROWS ONLY ) SELECT cte.id FROM table_email_upper AS a INNER JOIN cte ON a.sensitive_name=cte.sensitive_name;
1.3.3.6.5. LIGHTDB-MYSQL
1.3.3.6.5.1. 双冒号 ::
语法
将表达式转成特定类型
警告
支持将表达式转成 varchar、int、float、numeric
仅支持mysql到lightdb-msyql的转换
varchar支持带长度, numeric、float不支持带精度
示例
-- 转换前MySQL SQL:
insert into t1(c1, c2, c3, c4) values(123::varchar(10), '100'::int, '200'::float, '123.4'::numeric);
-- 转换后 SQL:
INSERT INTO "t1" ("c1","c2","c3","c4") VALUES (CAST(123 AS VARCHAR(10)),CAST('100' AS INT),CAST('200' AS FLOAT),CAST('123.4' AS NUMERIC))