2018 10 28

Oracleの元号設定

来年5月に元号が変わるのだが、決まっているのは変わることだけで、新元号は未だ不明。 カレンダー屋が筆頭の仕事で元号を扱っている連中は、せめて年内に新元号を決めてほしいと切望しているが、発表されるのは来年の3月か4月になるとのこと。 ギリギリまで公表しないのは社会の混乱を防ぐためだそうだ。

いや、ギリギリになって公表した方が社会の混乱を招くだろ。

と思っていたのだが、考えてみれば、日常生活で元号を意識する場面って役所用の書類を書くときだけなんだよな。 しかも役所の書類の元号はだいたい選択式だし、元年なら今が何年かと迷うこともない。

もっと長期的な役所向けの仕事の既に作成されている書類で 「平成40年って新元号で何年だっけ?」 と悩むことがあるかもしれないが、切り替わりの平成31年が新元号の元年なので、変換も簡単で覚えやすい。

要するに、元号が変わったところで混乱なんて発生しないのだ。 早い遅いを議論する意味もない。

「元号が変わることで口座とカードの切り替えが必要になります。 みたいな詐欺が増えるんじゃない?」

「その手の詐欺って、元号関係無しに増えてるでしょ」

「いやでもギリギリの公表でシステム変更が追いつかないことを理由に、銀行側でやるからカードを、みたいな」

「だったら、公表するときにその手の注意喚起も一緒にした方が、より効率的に届くでしょ」

「詐欺はそれでいいとして、IT関係はやっぱり大変じゃない? システムの切り替えとか」

「2000年問題のときもそんなこと言ってたけど、問題なんて起きなかったでしょ」

「それはあらかじめ準備したからでは?」

「だからその時に元号の変更ぐらい想定してるでしょ」

「確かに」

「ゆっくり決めればいいでしょ。 早く発表したってケチつけられるだけだし」

審議会も、こんな感じで進んだんじゃないかな。

さて、せっかく時間があることだし、俺もシステム屋の端くれとして、来たる日のために一つ準備をしておこう。

俺の周囲ではあまり使われていない、というか知られていない機能だが、Oracleには日付を元号で表示する機能がある。 例えばこう。

SQL> select to_char( sysdate, 'EEYY/MM/DD', 'NLS_CALENDAR=''Japanese Imperial''' ) as "和暦" from dual; 和暦 -------------------------------------- 平成30/10/28

検索個別ではなく、セッションに対して指定することもできる。

SQL> alter session set NLS_CALENDAR="Japanese Imperial"; セッションが変更されました。 SQL> select sysdate from dual; SYSDATE ------------------------------------------ 平成30年10月28日

カレンダー指定の Japanese Imperial が強そうで好き。 皇紀。

この機能を初めて知ったとき、ついでに元号が変わったときのための設定方法も調べておいたのだが、今日まで使う機会がなかった。 まあ、そりゃそうだろって話だが、しかし一度も試したことが無いってのもどうかと思うので、元号変更への準備として、ここで一度試しておく。

新元号がまだ決まっていないので、ここでは 「渡邊(W)」 にする。 明治(M)、大正(T)、昭和(S)、平成(H) のどれにも被らないので、可能性はまだ0では無いからね。

手順は大雑把に以下の通り。

  1. Oracleの内部文字コードを調べる。
  2. 新元号のEUCでの16進表現を調べる。
  3. カレンダーユーティリティlxegen用の設定ファイルを作る。
  4. カレンダーユーティリティlxegenを実行する。
  5. Oracleを再起動する。

まずは内部文字コードを調べる。 と大袈裟に言ってるが、やることはSQLを一つ実行するだけ。

SQL> select * from v$nls_parameters where parameter = 'NLS_CHARACTERSET'; PARAMETER VALUE ---------------- -------- NLS_CHARACTERSET JA16SJIS

次に、新元号のEUCでの16進表現を調べる。 これもSQLを実行するだけ。

フル元号を 「渡邊」 に、略号を 「W」 にするので、このそれぞれを調べる。

SQL> select dump( convert( '渡邊', 'JA16EUC', 'JA16SJIS' ), 16 ) from dual; DUMP(CONVERT('渡邊','JA1 ------------------------ Typ=1 Len=4: c5,cf,ee,b4 SQL> select dump( convert( 'W', 'JA16EUC', 'JA16SJIS' ), 16 ) from dual; DUMP(CONVERT('W --------------- Typ=1 Len=1: 57

ここまでの手順で得た情報から、カレンダーユーティリティーlxegenに食わせるファイルを作る。 設定項目と設定値は説明不要だろう。

DEFINE calendar calendar_name = "Japanese Imperial" DEFINE calendar_era era_full_name = c5cfeeb4 era_abbr_name = 57 start_date = "MAY-01-2019 AD" end_date = "DEC-31-2099 AD" ENDDEFINE calendar_era ENDDEFINE calendar

ファイルを保存する場所とファイル名は固定。 プラットフォーム依存ということだが、Windows系でもLinux系でも同じっぽい。

%ORACLE_HOME%¥nls¥lxecal.nlt

カレンダーユーティリティーlxegenを実行する。

Oracleをインストールした時にPATHも通っているようで、ただコマンドを実行するだけ。

C:¥> lxegen

実行すると、ファイルを置いた場所にコンパイル結果のファイルが作成される。

%ORACLE_HOME%¥nls¥lxecalji.nlb

Oracleを再起動して作業完了。

そしてテスト。

SQL> select to_char( to_date( '2019/05/01' ), 'eeyy/mm/dd', 'nls_calendar=''Japanese Imperial''' ) from dual; TO_CHAR(TO_DATE('2019/05/01'),'EEYY/MM -------------------------------------- 渡邊01/05/01

こうして表示されると、ちょっとした感動があるな。

と思ったのは最初だけだった。

あれこれ検索して表示させているうちにそんな感動はあっさり消えて、後は字画の多さばかりが目につくようになった。 渡邊の最初の正月が渡邊2年と中途半端だったりするし。 って、これは渡邊に限った話ではないか。 まあしかし、残念だが、元号に 「渡邊」 は無い。 自分の中で結論が出てしまった。

ということで設定を削除。

削除は、さっきlxegenで作ったファイルを削除してOracleを再起動するだけ。

ちなみにここまで、Macで発掘したVMWareのWindowsXPのOracle10gという化石のような環境でやっている。 というか、発掘したからやってみようと思ったのだが、まあそんなことはどうでも良いか。 Oracleが11gでも12cでもやることは同じ。