休日更新の備忘録

休日のみ更新予定の個人的備忘録置き場

【OracleDB】平成以降の元号を利用できるようにする(新元号「令和」対応!)

スポンサーリンク

【はじめに】

現在のOracleDatabaseには利用できる元号は平成までしかありません。
ここでは、OracleDatabaseに平成以降の元号を利用できるようにします。
※ 本記事での環境は以下の通り
OS:CentOS 7
データベース:OracleDatabase 12c(12.2.0)Enterprise Edition(無償版)
検証日:2019/1/19
更新日:2019/4/1

【手順】

手順1 現在の設定確認

① 以下コマンドを実行し、現在の文字コードを確認する。
select * from nls_database_parameters where PARAMETER = 'NLS_CHARACTERSET';
 結果:

 PARAMETER                      VALUE  
 ---------------------------------------------  
 NLS_CHARACTERSET               AL32UTF8  

手順2 新元号の16進数コード値を確認する。

① 以下コマンドを実行し元号文字列の16進数コード値を確認する。
 ※ ここでは元号文字列を「改元」と仮定する。
select dump(convert('改元', 'JA16EUC', 'AL32UTF8'), 16) from dual;
 結果:

 DUMP(CONVERT('改元','JA16EUC','AL32UTF8'),16)  
 ----------------------------------------------------------  
 Typ=1 Len=4: b2,fe,b8,b5  

ここで「convert」関数の第一引数には新元号として設定したい文字列を、第三引数には手順1-①で確認した文字コードを設定してください。

② 以下コマンドを実行し元号文字列(アルファベット表記)の16進数コード値を確認する。
 ※ ここでは元号文字列(アルファベット表記)を「K」と仮定する。
select dump('K', 16) from dual;
 結果:

 DUMP('K',16)  
 -----------------------------  
 Typ=96 Len=1: 4b  

手順3 新元号の定義ファイル作成・適用する。

① 以下コマンドを実行し、$ORACLE_HOME/nls配下に「lxecal.nlt」ファイルを作成する。
touch $ORACLE_HOME/nls/lxecal.nlt

② 手順3-①で作成した「lxecal.nlt」ファイルに以下を記述する。
 ※ 「era_full_name」には手順2-①で取得した値の「:(コロン)以降の,(カンマ)なし」の値を、
   「era_abbr_name」には手順2-②で取得した値の「:(コロン)以降」の値を、
   「start_date」には新しく追加したい元号の開始日(英語圏表記)を、
   「end_date」には新しく追加したい元号の終了日(英語圏表記)を記述する。

DEFINE calendar  
    calendar_name         = "Japanese Imperial"  
  
    DEFINE calendar_era  
        era_full_name     = "b2feb8b5"  
        era_abbr_name     = "4b"  
        start_date        = "JAN-10-2019 AD"  
        end_date          = "DEC-31-2200 AD"  
    ENDDEFINE calendar_era  
  
ENDDEFINE calendar  

③ 以下コマンドを実行し、データベースをシャットダウンする。
sqlplus / as sysdba
shutdown immediate;

④ 以下ファイルを実行し、「lxecal.nlt」をコンパイルする。
 ※ Windows環境では同じ格納先に「lxegen.exe」があるため、これを実行する。 $ORACLE_HOME/bin/lxegen
 → コマンドが正常終了すると、$ORACLE_HOME/nls配下に「lxecalji.nlb」というファイルが作成されている。

⑤ 以下コマンドを実行し、データベースをマウント・オープンする。
sqlplus / as sysdba
startup;

⑥ 以下コマンドの「sysdate」を適宜増減させ、新元号が適用されたか確認する。
select to_char(sysdate-10, 'EEYY"年"MM"月"DD"日"', 'NLS_CALENDAR = ''Japanese Imperial''') as 和暦日付 from dual;
 結果:

和暦日付  
--------------------------  
平成31年01月09日  

select to_char(sysdate-9, 'EEYY"年"MM"月"DD"日"', 'NLS_CALENDAR = ''Japanese Imperial''') as 和暦日付 from dual;
 結果:

和暦日付  
--------------------------  
改元01年01月10日  

【追記】

2019/4/1 5月以降の新元号は「令和」に決定!

 上記手順で2019/5/1以降の元号「令和」を適用した場合は以下のようになります。
① 以下コマンドを実行し、現在の文字コードを確認する。
select * from nls_database_parameters where PARAMETER = 'NLS_CHARACTERSET';
 結果:

 PARAMETER                      VALUE  
 ---------------------------------------------  
 NLS_CHARACTERSET               AL32UTF8  

② 以下コマンドを実行し元号文字列の16進数コード値を確認する。
select dump(convert('令和', 'JA16EUC', 'AL32UTF8'), 16) from dual;
 結果:

 DUMP(CONVERT('令和','JA16EUC','AL32UTF8'),16)  
 ----------------------------------------------------------  
 Typ=1 Len=4: ce,e1,cf,c2  

③ 以下コマンドを実行し元号文字列(アルファベット表記)の16進数コード値を確認する。
select dump('R', 16) from dual;
 結果:

 DUMP('R',16)  
 -----------------------------  
 Typ=96 Len=1: 52  

④ 「lxecal.nlt」ファイルに以下を記述する。

DEFINE calendar  
    calendar_name         = "Japanese Imperial"  
  
    DEFINE calendar_era  
        era_full_name     = "cee1cfc2"  
        era_abbr_name     = "52"  
        start_date        = "MAY-01-2019 AD"  
        end_date          = "DEC-31-2200 AD"  
    ENDDEFINE calendar_era  
  
ENDDEFINE calendar  

【おまけ】

おまけ① 予定の元号が変わったら

 手順3-④で作成される「lxecalji.nlb」は、「lxegen」が実行されるたびに"上書きで"作成されるため、
 予定とは違う元号にすると言われても再度手順をやりなおせば問題なく設定されます。

おまけ② 平成以降の元号が複数回変更されたら

 こちらは次回の記事にまとめます。
 ↓平成以降の元号が複数回変更された場合の対応方法こちら↓
www.holiday-note.tech

-- 以上 --

参考ページ
Oracle 製品における改元の影響について | NTTデータ先端技術株式会社
Oracle Database に 新しい元号(年号)「野球」を追加してみる。(NLSカレンダ・ユーティリティlxegen) ※2019/4/1追記:新元号「令和」の設定方法を追記 - Qiita
Oracle Database の DUMP関数 と CONVERT関数 で 文字列のバイトコードを調べる。 - Qiita