前文
他愛もない話だけど、たまたま気が付いたので備忘録として残す。
前提
本文の実行環境は Oracle Database 19c だけど、 多分どのバージョンでも同じ。
TO_CHAR
を使用した日付の書式化例は以下。
SQL> SELECT
TO_CHAR(SYSDATE, 'YYYY/MM/DD') 日本式
, TO_CHAR(SYSDATE, 'DD-MM-YYYY') 英国式
, TO_CHAR(SYSDATE, 'MM-DD-YYYY') 米国式
FROM DUAL
;
2 3 4 5 6
日本式 英国式 米国式
---------- ---------- ----------
2021/08/02 02-08-2021 08-02-2021
区切り文字の /
や -
等は予約語で、任意の文字は "
で囲めば使える。以下は "年"
"月"
"日"
を埋め込んだ例。
SQL> SELECT TO_CHAR(SYSDATE, 'YYYY"年"MM"月"DD"日"') FROM DUAL;
TO_CHAR(SYSDATE,'
-----------------
2021年08月02日
文法エラーについての考察
閉じ"
が抜ていれば当然文法エラー。以下は 年
の閉じ"
が抜ているケース。
SQL> SELECT TO_CHAR(SYSDATE, 'YYYY"年MM"月"DD"日"') FROM DUAL;
SELECT TO_CHAR(SYSDATE, 'YYYY"年MM"月"DD"日"') FROM DUAL
*
行1でエラーが発生しました。:
ORA-01821: 日付書式コードが無効です
ところが、最後の 日
の閉じ"
が抜ていてもエラーにならない。
SQL> SELECT TO_CHAR(SYSDATE, 'YYYY"年"MM"月"DD"日') FROM DUAL;
TO_CHAR(SYSDATE,'
-----------------
2021年08月02日
どうやら、閉じ"
が出てくる前に、書式化文字列の終端に達すると、終端までが "
で囲まれていると解釈される模様。
SQL> SELECT TO_CHAR(SYSDATE, 'YYYY"年MM月DD日') FROM DUAL;
TO_CHAR(SYSDATE,'
-----------------
2021年MM月DD日
"
で囲んで埋め込む文字は複数文字列でも構わないし。
SQL> SELECT TO_CHAR(SYSDATE, '"All your base are belong to us "YYYY') INTERNET_MEME FROM DUAL;
INTERNET_MEME
-----------------------------------
All your base are belong to us 2021
因みに、前出の 年
の閉じ"
が抜ているケース 'YYYY"年MM"月"DD"日"'
だけど、結果として "年MM"
が文字リテラルと解釈され、続く 月
が書式文字と解釈され、そんな予約語無いからエラーになっていると思われ。
「閉じ"
が出てくる前に、書式化文字列の終端に達すると」については、公式 からはそんな仕様は読み取れないけど、色々と動きを確認すると、そんな感じ。
それにしても閉じ"
が抜けているのに文法エラーにならないって一種のバグだよな。
Oracle の TO_CHAR
ってぐぐると、不審な動きの報告が色々と挙がっているようだし。謎が多いよ。