§ GreatSQL 高兼容
GreatSQL 实现 100% 完全兼容 MySQL 及 Percona 用法,支持大多数常见 Oracle 用法,包括 数据类型兼容、函数兼容、SQL 语法兼容、存储程序兼容 等众多兼容扩展用法。
§ Oracle兼容设计思路概述
GreatSQL的Oracle的兼容处理的优先原则如下:
- GreatSQL风格的SQL和存储程序可以直接在默认SQL MODE模式下工作。
 - 与GreatSQL风格的SQL和存储程序不冲突的Oracle兼容功能也可以直接在默认SQL MODE模式下工作。
 - 与GreatSQL风格的SQL和存储程序存在语法或语义冲突的功能,需要用户显式切换到Oracle MODE模式下才能工作。
 
GreatSQL对Oracle的兼容主要通过以下三种不同方案来实现:
- 原生模式:Oracle、GreatSQL都支持或部分支持通用的SQL标准,对于部分简单语句,无需调整即可兼容。
 - 兼容扩展:GreatSQL对于部分Oracle独有的函数和语法,在GreatSQL的Server层实现对其扩展,如:
MERGE INTO、CONNECT BY,这写类型的兼容特性无需额外设定SQL MODE,直接使用即可。 - 兼容模式:在GreatSQL中设置 
SET sql_mode = ORACLE;即可将当前会话切换到Oracle兼容模式。在该模式下,当Oracle语法与GreatSQL语法存在语法或语义上的冲突时,GreatSQL会自行选择Oracle兼容模式。 
更多关于Oracle兼容模式的说明请查看文档:Oracle mode。
§ 数据类型兼容
在GreatSQL中,采用映射方式实现数据类型兼容,这属于 扩展兼容(无需设定 sql_mode) 方案。具体实现方式为:简单别名,即:在解析阶段将关键词进行替换。例如:如果使用CLOB创建的表,在系统内会被转换成LONGTEXT。
具体实现的映射包括:
| Oracle类型 | GreatSQL类型 | 兼容程度 | 
|---|---|---|
| CLOB | LONGTEXT | 简单别名 | 
| NUMBER | DECIMAL | 简单别名 | 
| VARCHAR2 | VARCHAR | 简单别名 | 
| PLS_INTEGER | INT | 简单别名 | 
示例:
greatsql> CREATE TABLE t1(
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
c1 CLOB NOT NULL DEFAULT '', 
c2 VARCHAR2(30) NOT NULL DEFAULT '');
ERROR 1101 (42000): BLOB, TEXT, GEOMETRY or JSON column 'c1' can't have a default value
greatsql> CREATE TABLE t1(
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 
c1 CLOB NOT NULL, 
c2 VARCHAR2(30) NOT NULL DEFAULT '');
Query OK, 0 rows affected (0.25 sec)
greatsql> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `c1` longtext NOT NULL,
  `c2` varchar(30) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.01 sec)
 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
更详细信息请参考 数据类型兼容。
§ SQL语法兼容
§ 扩展兼容支持的 SQL 语法
下面是在 GreatSQL 中无需设定 sql_mode = ORACLE 就能支持的SQL语法:
- ANY, ALL
 - CREATE FORCE VIEW
 - Hierarchical Query(分层查询)
 - DATETIME INTERVAL
 - EXECUTE IMMEDIATE
 - EXPLAIN PLAN FOR
 - EXTERNAL TABLE
 - FULL JOIN
 - INSERT ALL INTO
 - KEEP FIRST/LAST
 - MERGE INTO
 - MINUS
 - ORACLE HINT
 - ROWNUM
 - SELECT...FOR UPDATE OF COLUMNS
 - SELECT...OFFSET...FETCH
 - SEQUENCE
 - (+) 外连接
 - 子查询无别名
 - 空串''与NULL等价开关
 - 字符串列设置CURRENT_TIMESTAMP默认值
 - 移除指定sql_mode
 - 更多 ...
 
§ 兼容模式支持的 SQL 语法
下面是在 GreatSQL 中需要先设定 sql_mode = ORACLE 才能支持的SQL语法:
- CREATE TYPE
 - CREATE TABLE OF TYPE
 - DATETIME加减运算
 - DELETE语句支持不带FROM
 - EXEC
 - ORDER BY兼容
 - PIVOT
 - RATIO_TO_REPORT
 - SELECT...FOR UPDATE WAIT N
 - SQLCODE_SQLERRM_FUNCTION
 - SYSDATE_IS_NOW模式
 - TABLE FUNCTION
 - TABLE UDT
 - UPDATE SET多字段更新
 - WITH FUNCTION
 - 全局临时表
 - 带双引号的存储过程创建
 - Oracle注释风格
 - 索引中NULL视为相同值
 - 更多 ...
 
§ 函数兼容
§ 扩展兼容支持的函数
下面是在 GreatSQL 中无需设定 sql_mode = ORACLE 就能支持的函数:
- ADD_MONTHS
 - CAST
 - CHR
 - CURRENT_TIMESTAMP
 - DECODE
 - DUMP
 - INITCAP
 - INSTRB
 - LENGTHB
 - LIST_AGG
 - MONTHS_BETWEEN
 - NCHR
 - NVL
 - NVL2
 - RAWTOHEX
 - REGEXP_COUNT
 - REGEXP_REPLACE
 - REPLACE
 - SUBSTRB
 - SYS_GUID
 - SYSTIMESTAMP
 - TO_CHAR
 - TO_CLOB
 - TO_DATE
 - TO_NUMBER
 - TO_TIMESTAMP
 - TRANSLATE
 - TRUNC
 - VSIZE
 - WM_CONCAT
 - 更多 ...
 
§ 兼容模式支持的函数
下面是在 GreatSQL 中需要先设置 sql_mode = ORACLE 才能支持的函数:
注意:以上函数在设定 sql_mode = ORACLE 后,行为与Oracle会更加接近;反之则保持GreatSQL的原生行为。
§ 存储程序兼容
GreatSQL支持Oracle风格的存储程序使用方式,部分存储程序部分在 ORACLE 模式下做了基础结构改造,详见:存储程序基础结构改造说明。
§ 扩展兼容支持的存储程序
下面是在 GreatSQL 中,无论 sql_mode 采用 DEFAULT 还是 ORACLE,都能支持 CREATE OR REPLACE扩展,但是在不同模式下的表现也有所区别。
§ 兼容模式支持的存储程序
下面是需要先设定 sql_mode = ORACLE 才能支持 Oracle 兼容的存储程序用法(部分用法在 sql_mode = DEFAULT 模式下也支持,但不具备 Oracle 兼容特性)
- BULK COLLECT
 - CONTINUE
 - CURSOR
 - EXIT/EXIT WHEN
 - FORALL LOOP
 - FOR LOOP
 - GOTO
 - IF .. ELSIF
 - REF CURSOR, SYS_REFCURSOR
 - TRIGGER
 - TYPE IS RECORD
 - TYPE IS TABLE
 - VAR_TYPE
 - WHILE...LOOP... END LOOP
 - 匿名存储块
 - 命名标记法传递参数
 - 存储程序支持默认参数(DEFAULT)
 - 存储过程支持使用RETURN
 - 异常处理 EXCEPTION HANDLER
 - 更多 ...
 
示例:
- Oracle环境下的存储程序用法:
 
CREATE OR REPLACE EDITIONABLE FUNCTION f0(delta INT DEFAULT 0) RETURN TIMESTAMP AS
    cnt INT := 10;
BEGIN
    RETURN SYSDATE + delta*cnt;
END;
SELECT f0(2) FROM DUAL ;
SELECT f0() FROM DUAL ;
 2
3
4
5
6
7
8
- GreatSQL 原生模式下的存储程序用法:
 
CREATE OR REPLACE FUNCTION f1(delta INT) RETURNS TIMESTAMP
BEGIN
    DECLARE cnt INT DEFAULT 10;
    SET delta = cnt * delta;
    RETURN DATE_ADD(SYSDATE(), INTERVAL delta DAY);
END;
SELECT f0(2) FROM DUAL ;
 2
3
4
5
6
7
8
- GreatSQL 兼容模式 下存储程序用法:
 
SET sql_mode = ORACLE;
CREATE OR REPLACE FUNCTION f0(delta INT DEFAULT 0) RETURN TIMESTAMP AS
    cnt INT := 10;
BEGIN
    RETURN SYSDATE + delta*cnt;
END;
SELECT f0(2) FROM DUAL ;
SELECT f0() FROM DUAL ;
 2
3
4
5
6
7
8
9
10
Oracle 兼容常见问题详见:Oracle 兼容常见问题。
扫码关注微信公众号
