Oracle と TiDB の関数と構文の比較

このドキュメントでは、Oracle と TiDB の関数と構文の比較について説明します。 Oracle 関数に基づいて対応する TiDB 関数を見つけ、Oracle と TiDB の構文の違いを理解するのに役立ちます。

ノート:

このドキュメントの関数と構文は、Oracle 12.2.0.1.0 および TiDB v5.4.0 に基づいています。他のバージョンでは異なる場合があります。

関数比較

次の表は、いくつかの Oracle と TiDB の関数の比較を示しています。

関数オラクルの構文TiDB 構文ノート
値を特定の型としてキャストする
  • TO_NUMBER(key)
  • TO_CHAR(key)
  • CONVERT(key,dataType)TiDB は、値を次の型のいずれかとしてキャストすることをサポートしています: BINARYCHARDATEDATETIMETIMESIGNED INTEGERUNSIGNED INTEGER 、およびDECIMAL
    日付を文字列に変換する
  • TO_CHAR(SYSDATE,'yyyy-MM-dd hh24:mi:ss')
  • TO_CHAR(SYSDATE,'yyyy-MM-dd')
  • DATE_FORMAT(NOW(),'%Y-%m-%d %H:%i:%s')
  • DATE_FORMAT(NOW(),'%Y-%m-%d')
  • TiDB のフォーマット文字列は大文字と小文字が区別されます。
    文字列を日付に変換する
  • TO_DATE('2021-05-28 17:31:37','yyyy-MM-dd hh24:mi:ss')
  • TO_DATE('2021-05-28','yyyy-MM-dd hh24:mi:ss')
  • STR_TO_DATE('2021-05-28 17:31:37','%Y-%m-%d %H:%i:%s')
  • STR_TO_DATE('2021-05-28','%Y-%m-%d%T')
  • TiDB のフォーマット文字列は大文字と小文字が区別されます。
    現在のシステム時刻を秒精度で取得するSYSDATENOW()
    現在のシステム時刻をマイクロ秒の精度で取得しますSYSTIMESTAMPCURRENT_TIMESTAMP(6)
    2 つの日付間の日数を取得するdate1 - date2DATEDIFF(date1, date2)
    2 つの日付の間の月数を取得するMONTHS_BETWEEN(ENDDATE,SYSDATE)TIMESTAMPDIFF(MONTH,SYSDATE,ENDDATE)Oracle のMONTHS_BETWEEN()と TiDB のTIMESTAMPDIFF()の結果は異なります。 TIMESTAMPDIFF()は整数を返します。 2 つの関数のパラメーターが入れ替わっていることに注意してください。
    日付にn日を加算するDATEVAL + nDATE_ADD(dateVal,INTERVAL n DAY)nは負の値にすることができます。
    日付にnか月を加算するADD_MONTHS(dateVal,n)DATE_ADD(dateVal,INTERVAL n MONTH)nは負の値にすることができます。
    デートの日を取得するTRUNC(SYSDATE)
  • CAST(NOW() AS DATE)
  • DATE_FORMAT(NOW(),'%Y-%m-%d')
  • TiDB では、 CASTDATE_FORMATは同じ結果を返します。
    日付の月を取得するTRUNC(SYSDATE,'mm')DATE_ADD(CURDATE(),interval - day(CURDATE()) + 1 day)
    値を切り捨てるTRUNC(2.136) = 2
    TRUNC(2.136,2) = 2.13
    TRUNCATE(2.136,0) = 2
    TRUNCATE(2.136,2) = 2.13
    データの精度は維持されます。丸めずに対応する小数点以下を切り捨てます。
    シーケンス内の次の値を取得するsequence_name.NEXTVALNEXTVAL(sequence_name)
    ランダムなシーケンス値を取得するSYS_GUID()UUID()TiDB は Universal Unique Identifier (UUID) を返します。
    左結合または右結合SELECT * FROM a, b WHERE a.id = b.id(+);
    SELECT * FROM a, b WHERE a.id(+) = b.id;
    SELECT * FROM a LEFT JOIN b ON a.id = b.id;
    SELECT * FROM a RIGHT JOIN b ON a.id = b.id;
    相関クエリでは、TiDB は (+) を使用した左結合または右結合をサポートしていません。代わりにLEFT JOINまたはRIGHT JOINを使用できます。
    NVL()NVL(key,val)IFNULL(key,val)フィールドの値がNULLの場合はvalを返します。それ以外の場合は、フィールドの値を返します。
    NVL2()NVL2(key, val1, val2)IF(key is NULL, val1, val2)フィールドの値がNULLでない場合はval1を返します。それ以外の場合はval2を返します。
    DECODE()
  • DECODE(key,val1,val2,val3)
  • DECODE(value,if1,val1,if2,val2,...,ifn,valn,val)
  • IF(key=val1,val2,val3)
  • CASE WHEN value=if1 THEN val1 WHEN value=if2 THEN val2,...,WHEN value=ifn THEN valn ELSE val END
  • フィールドの値がval1の場合はval2を返します。それ以外の場合はval3を返します。
  • フィールドの値が条件 1 ( if1 ) を満たす場合、 val1を返します。条件 2 ( if2 ) を満たす場合はval2を返します。条件 3 ( if3 ) を満たす場合はval3を返します。
  • 文字列abを連結する`'a''b'`CONCAT('a','b')
    文字列の長さを取得するLENGTH(str)CHAR_LENGTH(str)
    指定された部分文字列を取得するSUBSTR('abcdefg',0,2) = 'ab'
    SUBSTR('abcdefg',1,2) = 'ab'
    SUBSTRING('abcdefg',0,2) = ''
    SUBSTRING('abcdefg',1,2) = 'ab'
  • Oracle では、開始位置 0 は 1 と同じ効果があります。
  • TiDB では、開始位置 0 は空の文字列を返します。先頭から部分文字列を取得する場合は、開始位置を 1 にする必要があります。
  • 部分文字列の位置を取得するINSTR('abcdefg','b',1,1)INSTR('abcdefg','b')'abcdefg'の最初の文字から検索し、 'b'が最初に出現する位置を返します。
    部分文字列の位置を取得するINSTR('stst','s',1,2)LENGTH(SUBSTRING_INDEX('stst','s',2)) + 1'stst'の最初の文字から検索し、2 番目に出現する's'の位置を返します。
    部分文字列の位置を取得するINSTR('abcabc','b',2,1)LOCATE('b','abcabc',2)abcabcの 2 文字目から検索し、最初にbが出現する位置を返します。
    列の値を連結するLISTAGG(CONCAT(E.dimensionid,'---',E.DIMENSIONNAME),'***') within GROUP(ORDER BY DIMENSIONNAME)GROUP_CONCAT(CONCAT(E.dimensionid,'---',E.DIMENSIONNAME) ORDER BY DIMENSIONNAME SEPARATOR '***')指定した列の値を区切り文字 1 で***つの行に連結します。
    ASCII コードを文字に変換するCHR(n)CHAR(n)Oracle の Tab ( CHR(9) )、LF ( CHR(10) )、および CR ( CHR(13) ) 文字は、TiDB のCHAR(9)CHAR(10) 、およびCHAR(13)に対応します。

    構文の比較

    このセクションでは、Oracle と TiDB の構文の違いについて説明します。

    文字列構文

    Oracle では、文字列は一重引用符 ('') でのみ囲むことができます。たとえば'a'

    TiDB では、文字列を一重引用符 ('') または二重引用符 ("") で囲むことができます。たとえば、 'a'"a"です。

    NULLと空の文字列の違い

    Oracle はNULLと空の文字列''を区別しません。つまり、 NULL''と同等です。

    TiDB はNULLと空の文字列''を区別します。

    INSERTステートメントで同じテーブルを読み書きする

    Oracle は、 INSERTのステートメントで同じテーブルへの読み取りと書き込みをサポートしています。例えば:

    INSERT INTO table1 VALUES (feild1,(SELECT feild2 FROM table1 WHERE...))

    TiDB は、 INSERTステートメントでの同じテーブルへの読み取りと書き込みをサポートしていません。例えば:

    INSERT INTO table1 VALUES (feild1,(SELECT T.fields2 FROM table1 T WHERE...))

    クエリから最初の n 行を取得する

    Oracle では、クエリから最初の n 行を取得するには、 ROWNUM <= n句を使用できます。たとえばROWNUM <= 10

    TiDB では、クエリから最初の n 行を取得するには、 LIMIT n句を使用できます。たとえばLIMIT 10LIMITの SQL ステートメントを実行する Hibernate Query Language (HQL) はエラーになります。 Hibernate ステートメントを SQL ステートメントに変更する必要があります。

    UPDATEステートメントで複数のテーブルを更新する

    Oracle では、複数のテーブルを更新する場合、特定のフィールド更新関係をリストする必要はありません。例えば:

    UPDATE test1 SET(test1.name,test1.age) = (SELECT test2.name,test2.age FROM test2 WHERE test2.id=test1.id)

    TiDB では、複数のテーブルを更新する場合、特定のフィールド更新関係をすべてSETにリストする必要があります。例えば:

    UPDATE test1,test2 SET test1.name=test2.name,test1.age=test2.age WHERE test1.id=test2.id

    派生テーブルのエイリアス

    Oracle では、複数のテーブルをクエリする場合、派生テーブルにエイリアスを追加する必要はありません。例えば:

    SELECT * FROM (SELECT * FROM test)

    TiDB では、複数のテーブルにクエリを実行する場合、すべての派生テーブルに独自のエイリアスが必要です。例えば:

    SELECT * FROM (SELECT * FROM test) t

    セット操作

    Oracle では、最初のクエリ結果に含まれるが 2 番目のクエリ結果には含まれない行を取得するには、 MINUSセット操作を使用できます。例えば:

    SELECT * FROM t1 MINUS SELECT * FROM t2

    TiDB はMINUS操作をサポートしていません。 EXCEPTセット運用ができます。例えば:

    SELECT * FROM t1 EXCEPT SELECT * FROM t2

    コメント構文

    Oracle では、コメント構文は--Commentです。

    TiDB では、コメント構文は-- Commentです。 TiDB では--の後に空白があることに注意してください。

    ページネーション

    Oracle では、 OFFSET m ROWSを使用してm行をスキップし、 FETCH NEXT n ROWS ONLYを使用してn行をフェッチできます。例えば:

    SELECT * FROM tables OFFSET 0 ROWS FETCH NEXT 2000 ROWS ONLY

    TiDB では、 LIMIT n OFFSET mを使用してOFFSET m ROWS FETCH NEXT n ROWS ONLYを置き換えることができます。例えば:

    SELECT * FROM tables LIMIT 2000 OFFSET 0

    NULL値のソート順

    Oracle では、次の場合にNULLの値がORDER BY句でソートされます。

    • ORDER BY column ASCステートメントでは、最後にNULLの値が返されます。

    • ORDER BY column DESCステートメントでは、最初にNULLの値が返されます。

    • ORDER BY column [ASC|DESC] NULLS FIRSTステートメントでは、非 NULL 値の前にNULLの値が返されます。非 NULL 値は、 ASC|DESCで指定された昇順または降順で返されます。

    • ORDER BY column [ASC|DESC] NULLS LASTステートメントでは、非 NULL 値の後にNULLの値が返されます。非 NULL 値は、 ASC|DESCで指定された昇順または降順で返されます。

    TiDB では、次の場合にNULLの値がORDER BY句でソートされます。

    • ORDER BY column ASCステートメントでは、最初にNULLの値が返されます。

    • ORDER BY column DESCステートメントでは、最後にNULLの値が返されます。

    次の表は、Oracle と TiDB における同等のORDER BYステートメントの例を示しています。

    オラクルでORDER BYTiDB の同等のステートメント
    SELECT * FROM t1 ORDER BY name NULLS FIRST;SELECT * FROM t1 ORDER BY name;
    SELECT * FROM t1 ORDER BY name DESC NULLS LAST;SELECT * FROM t1 ORDER BY name DESC;
    SELECT * FROM t1 ORDER BY name DESC NULLS FIRST;SELECT * FROM t1 ORDER BY ISNULL(name) DESC, name DESC;
    SELECT * FROM t1 ORDER BY name ASC NULLS LAST;SELECT * FROM t1 ORDER BY ISNULL(name), name;