體驗(yàn)MariaDB 10.3中的Oracle語(yǔ)法支持

一、背景

MariaDB 10.3發(fā)布已經(jīng)有一段時(shí)間了官辽,里面提到了SQL_MODE新增了ORACLE選項(xiàng)蛹磺,可以支持部分的PL/SQL語(yǔ)法,算是一個(gè)比較“新鮮”的更新同仆,所以打算安裝體驗(yàn)一下萤捆,并測(cè)試支持情況。

二俗批、測(cè)試環(huán)境

硬件:
CPU:i5-8250U (四核八線程)
內(nèi)存:8GB
磁盤:240GB SSD

系統(tǒng)平臺(tái):win10 x64

數(shù)據(jù)庫(kù):MariaDB-10.3.9-winx64

三俗或、準(zhǔn)備測(cè)試數(shù)據(jù)

use test;

CREATE TABLE t_A (
id   int,
code   int,
name  VARCHAR(10)
);
 
CREATE TABLE t_B (
id   int,
code   int,
name  VARCHAR(10)
);
 
INSERT INTO t_A(id,code,name) VALUES(1,2,'A');
INSERT INTO t_A(id,code,name) VALUES(2,1,'B');
INSERT INTO t_A(id,code,name) VALUES(3,5,'C');
INSERT INTO t_A(id,code,name) VALUES(4,6,'D');
INSERT INTO t_A(id,code,name) VALUES(5,7,'E');
 
INSERT INTO t_B(id,code,name) VALUES(1,3,'AA');
INSERT INTO t_B(id,code,name) VALUES(1,4,'BB');
INSERT INTO t_B(id,code,name) VALUES(2,1,'CC');
INSERT INTO t_B(id,code,name) VALUES(1,2,'DD');
INSERT INTO t_B(id,code,name) VALUES(7,5,'GG');

CREATE TABLE temp (
id   int,
code   int,
name  VARCHAR(50)
);

四、測(cè)試oracle語(yǔ)法支持

1岁忘、體驗(yàn)一下SQL_MODE="ORACLE"

Oracle中的示例文檔中代碼(Sample 1. FOR Loop):

-- available online in file 'sample1'
DECLARE
   x NUMBER := 100;
BEGIN
   FOR i IN 1..10 LOOP
      IF MOD(i,2) = 0 THEN     -- i is even
         INSERT INTO temp VALUES (i, x, 'i is even');
      ELSE
         INSERT INTO temp VALUES (i, x, 'i is odd');
      END IF;
      x := x + 100;
   END LOOP;
   COMMIT;
END;</pre>

我們看看如果是這樣一段代碼辛慰,要在MySQL中運(yùn)行,應(yīng)該看起來(lái)是怎樣的干像。下面是修改在MySQL5.7中運(yùn)行的代碼:

CREATE PROCEDURE dowhile()
BEGIN
    DECLARE   x INT DEFAULT 100; 
    DECLARE   i INT DEFAULT 1;

   WHILE i <= 10 DO
      IF MOD(i,2) = 0 THEN     -- i is even
         INSERT INTO temp VALUES (i, x, 'i is even');
      ELSE
         INSERT INTO temp VALUES (i, x, 'i is odd');
      END IF;
      
   COMMIT;
   SET x=x+100;
   SET i=i+1;  
 END WHILE;  
END;

以上兩種帅腌,主要的不同包括:

MySQL代碼必須在一個(gè)存儲(chǔ)過(guò)程中執(zhí)行辱志,所以這里創(chuàng)建了dowhile

  • DECLARE語(yǔ)法不一樣,Oracle DECLARE在BEGIN之前狞膘,MySQL則在BEGIN里面
  • MySQL不支持FOR... IN... LOOP的語(yǔ)法揩懒,這里改用WHILE來(lái)實(shí)現(xiàn);MySQL也不支持"1..10"這種寫法
  • 數(shù)據(jù)類型不同挽封,Oracle中是NUMBER已球,MySQL是INT
  • 變量賦值不同,Oracle使用了“:=”辅愿,MySQL是 “SET .. = ...”
    我們先看看智亮,前一段Oracle的代碼,在MariaDB里面是否能夠不做修改的運(yùn)行:

這個(gè)簡(jiǎn)單的示例可以正常運(yùn)行:

Enter password: ******
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 13
Server version: 10.3.9-MariaDB mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> use test
Database changed
MariaDB [test]> select * from temp;
Empty set (0.003 sec)

MariaDB [test]> show variables like 'sql_mode';
+---------------+-------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                     |
+---------------+-------------------------------------------------------------------------------------------+
| sql_mode      | STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+-------------------------------------------------------------------------------------------+
1 row in set (0.003 sec)

MariaDB [test]> set session sql_mode="ORACLE";
Query OK, 0 rows affected (0.000 sec)

MariaDB [test]> show variables like 'sql_mode';
+---------------+----------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                                                                        |
+---------------+----------------------------------------------------------------------------------------------------------------------------------------------+
| sql_mode      | PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT |
+---------------+----------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.003 sec)

MariaDB [test]> delimiter /
MariaDB [test]> DECLARE
    ->    x NUMBER := 100;
    -> BEGIN
    ->    FOR i IN 1..10 LOOP
    ->       IF MOD(i,2) = 0 THEN     -- i is even
    ->          INSERT INTO temp VALUES (i, x, 'i is even');
    ->       ELSE
    ->          INSERT INTO temp VALUES (i, x, 'i is odd');
    ->       END IF;
    ->       x := x + 100;
    ->    END LOOP;
    ->    COMMIT;
    -> END;
    -> /
Query OK, 10 rows affected (0.020 sec)

MariaDB [test]> select * from temp/
+------+------+-----------+
| 列 1 | 列 2 | 列 3      |
+------+------+-----------+
|    1 |  100 | i is odd  |
|    2 |  200 | i is even |
|    3 |  300 | i is odd  |
|    4 |  400 | i is even |
|    5 |  500 | i is odd  |
|    6 |  600 | i is even |
|    7 |  700 | i is odd  |
|    8 |  800 | i is even |
|    9 |  900 | i is odd  |
|   10 | 1000 | i is even |
+------+------+-----------+
10 rows in set (0.000 sec)

2点待、測(cè)試oracle的外關(guān)聯(lián)語(yǔ)法

oracle專用標(biāo)準(zhǔn)的關(guān)聯(lián)查詢阔蛉,以兩個(gè)關(guān)聯(lián)鍵值的左關(guān)聯(lián)SQL為例。

select * 
from t_a a,t_b b 
where a.id=b.id(+) and a.code=b.code(+) 
    and a.id!=8;

轉(zhuǎn)換為ANSI標(biāo)準(zhǔn)的left /right/full join 的寫法如下:

select * 
from t_a a 
left join t_b b on a.id=b.id and a.code=b.code
where a.id!=8;

測(cè)試情況:

MariaDB [test]> select *
    -> from t_a a
    -> left join t_b b on a.id=b.id and a.code=b.code
    -> where a.id!=8;
    -> /
+------+------+------+------+------+------+
| id   | code | name | id   | code | name |
+------+------+------+------+------+------+
|    2 |    1 | B    |    2 |    1 | CC   |
|    1 |    2 | A    |    1 |    2 | DD   |
|    3 |    5 | C    | NULL | NULL | NULL |
|    4 |    6 | D    | NULL | NULL | NULL |
|    5 |    7 | E    | NULL | NULL | NULL |
+------+------+------+------+------+------+
5 rows in set (0.004 sec)

MariaDB [test]> select *
    -> from t_a a,t_b b
    -> where a.id=b.id(+) and a.code=b.code(+)
    ->     and a.id!=8;
    -> /
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') and a.code=b.code(+)
    and a.id!=8' at line 3
MariaDB [test]>

不支持oracle的(+)表示外關(guān)聯(lián)的語(yǔ)法

最后

目前還沒(méi)有完整量化評(píng)估MariaDB對(duì)PL/SQL的支持情況癞埠,對(duì)于oracle的外關(guān)聯(lián)語(yǔ)法(+)在oracle中的廣泛使用状原,目前還沒(méi)有得到支持。也許在后續(xù)的版本中苗踪,會(huì)逐步完善對(duì)oracle語(yǔ)法的兼容性颠区。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市通铲,隨后出現(xiàn)的幾起案子毕莱,更是在濱河造成了極大的恐慌,老刑警劉巖颅夺,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朋截,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡吧黄,警方通過(guò)查閱死者的電腦和手機(jī)部服,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)稚字,“玉大人饲宿,你說(shuō)我怎么就攤上這事胆描〔玻” “怎么了短绸?”我有些...
    開(kāi)封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵窄驹,是天一觀的道長(zhǎng)乐埠。 經(jīng)常有香客問(wèn)我囚企,道長(zhǎng)丈咐,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任龙宏,我火速辦了婚禮棵逊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘银酗。我一直安慰自己,他們只是感情好黍特,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布秸歧。 她就那樣靜靜地躺著,像睡著了一般衅澈。 火紅的嫁衣襯著肌膚如雪经备。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼浸卦。 笑死靴庆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的端礼。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼凡桥,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蚀同?” 一聲冷哼從身側(cè)響起缅刽,我...
    開(kāi)封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎衰猛,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卦睹,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡方库,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年纵潦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了徐鹤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邀层。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡返敬,死狀恐怖被济,靈堂內(nèi)的尸體忽然破棺而出只磷,到底是詐尸還是另有隱情钮追,我是刑警寧澤预厌,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站元媚,受9級(jí)特大地震影響轧叽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜刊棕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一炭晒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧甥角,春花似錦网严、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至当犯,卻和暖如春垢村,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嚎卫。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工嘉栓, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拓诸。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓胸懈,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親恰响。 傳聞我的和親對(duì)象是個(gè)殘疾皇子趣钱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容