弁財天

ゴフマン「専門家を信じるのではなく、自分自身で考えて判断せよ」

20年前に作製されたCOBOLコードを NLS_LANG=Japanese_JAPAN.AL32UTF8 と LANG=ja_JP.UTF-8 で JIS X 0213:2004 に対応させるw。update2

JIS X 0213:2004
からCOBOLのJIS X 0213:2004対応を切り出し。

oracle.com→PDFもう文字化けには悩まない!Oracle Database 11g R2ならWindows 7クライアントでもばっちり!
外字のためにデータベースをUnicodeにする必要はないが
JIS X 0213:2004でデータベースを読み書きするには
NLS_CHARACTERSET=AL32UTF8
にする必要がある。
Oracleインスタンスの文字コードをAL32UTF8にして、…
export NLS_LANG=Japanese_JAPAN.AL32UTF8
export LANG=ja_JP.UTF-8
に設定してJavaやCOBOLでデータベースにアクセスする。

環境変数を変えるだけかぁ。簡単じゃーん、と思った人は大間違いw。

これは20年前にSJISを想定して文字列を編集するコードを、UTF-8に対応するロジックに書き換えることを意味する。ありえねー。無理無理w。

RHEL6/7ではlocaledefで LANG=ja_JP.SJISをSHIFT_JIS以外に、
WINDOWS-31J(cp932)に設定したり、
SHIFT_JISX0213に設定することもできる。

# localedef -i ja_JP -f WINDOWS-31J ja_JP.SJIS
# localedef -i ja_JP -f SHIFT_JISX0213  ja_JP.SJIS

microfocus.co.jp→Micro Focus COBOL アプリケーション互換性ガイド(2017年8月28日)

しかしOracleクライアントがサポートするのは
NLS_LANG=Japanese_Japan.JA16SJISと
NLS_LANG=Japanese_Japan.JA16SJISTILDEだけだ。

NLS_LANG=Japanese_Japan.JA16CP932とか、
NLS_LANG=Japanese_Japan.JA32JISX0213などは存在しない。

Oracleデータベースのクライアントは、
LANG=ja_JP.UTF8と
NLS_LANG=Japanese_Japan.AL32UTF8を
組み合わせた環境でJIS X 0213:2004に対応することになってる。

shift-the-oracle.com→AL32UTF8 で補助文字(4バイトの文字)の扱い (JIS X 0213:2004 / 第3・4水準漢字)

AL32UTF8 で補助文字(4バイトの文字)の扱い (JIS X 0213:2004 / 第3・4水準漢字)
Windows Vista による JIS X 0213:2004 サポートによって 4 バイト文字の問題が顕在化する可能性も…
Oracle 10g R1 は 3 バイトまでの Unicode 3.2 Oracle 10g R2 から AL32UTF32 と AL16UTF16 で Unicode 4.0 サポート Oracle 10g Release2 Oracle 11g から AL32UTF32 と AL16UTF16 で Unicode 5.0 サポート Oracle 11g 5.0 なら補助文字は 4 バイト
マニュアル上の表記では(Oracle 10g R1 以前まで?)
UTF8 データベースに補助文字が挿入されても、データベース内のデータは 破損しません。 補助文字は 6バイトを占める 2つの別個のユーザー定義文字 として処理されます。

と書かれている。つまり 4バイト文字は 6バイト消費するということのようである。(つまり AL32UTF8 には Oracle による拡張が施されている。NCHAR の UTF8 は???)
但し、未確認 & TTC レイヤ、ミドルウェアのバージョンによっては予想外の動作になるかもしれない。

クライアント(顧客)が Windows Vista 使用を解禁した後に発生が予想されるエラー
ORA-06502: PL/SQL: 数値または値のエラー: 文字列バッファが小さすぎます
ORA-12899: 列 string の値が大きすぎます(実際: string、最大: string)

microfocus.co.jp→COBOLによるUnicodeデータ処理(2014年12月第2版)
LANG=ja_JP.UTF-8と、NLS_LANG=Japanese_Japan.AL32UTF8に設定したときの COBOLコードの対応方法。

「Visual COBOLはバージョン 2.2 Update 2よりUTF-8データをCOBOLプログラムでハンドリングする際に有用な組み込み関数を追加いたしました。」w

MicroFocus COBOLのULENGTH関数、UPOS 関数、USUBSTR 関数、USUPPLEMENTARY 関数、UVALID 関数、UWIDTH 関数を駆使してソースコードを全面的に書き換えるのか。

おぉぉ。なんて恐ろしいドキュメントなんだ。ユニコード対応だけでソースコードを全面的に書き換えw。表やCOBOLのPIC X(n)のフィールド長を増やすだけでは対応できない。約300万行のソースを修正かぁ。

なんかユニコードに対応するCOBOLプリコンパイラを開発すると売れそーw。(誰に?

まぁ、そこまでやるのならMicroFocusを捨ててGnuCOBOLに書き換えるだろう。
GnuCOBOL (formerly OpenCOBOL)→ standardizing on UTF-16 instead of UTF-8 ?

なぜならMicroFocusのライセンス体系では大規模な開発テストができないからだ。
CMDTUX_CAT:819: 情報: プロセスID=7520 Assumeを起動しました(パイプ)。

ITモダナイゼーションSummit 2016→OSS COBOLの最新動向とモダナイゼーション事例のご紹介(2016年4月26日)

海外– フランス財務省
MicroFocus→OpenCOBOL
フランス財務省は英MicroFocusのライセンス料金がいちばん気になった?w
いやいや、フランスはMicroFocusのライセンスマネージャーのあやしいUDP通信が気になったのだw。

opensquare.co.jp→オープンソースでのCOBOLの基幹システム開発

うは。Linux + Pro*COBOL + OpenCOBOL + Tuxedo + Oracleデータベースサーバで国内実績があるw。

ここまではサーバーサイドの話だ。
Win10側で動作する20年前のVB6をVB.NetとTuxedoクライアントで64ビット対応(PE32+)にしてSJISのVC++のDLLのソースコードをユニコードに対応させる改修も発生する。

office-qa.com→Windows7:日本語入力環境について(JIS2004対応とは)

Windows7のMS-IMEではJIS X 0208以外の変換候補に「環境依存文字(Unicode)」のコメントを表示し、注意を促しています。
Win7からJIS X 0213:2004はIMEで環境依存文字(Unicode)の警告が表示されるが入力可能になっている。 しかしシフトJISで設計したTuxedoの電文にUnicodeを乗せることはできないw。 ここでもCOBOL側と同じようなVB.Netの電文定義体、VC++のDLLの電文定義体の改修も発生する。

dobon.net→目的の文字コードに合ったEncodingオブジェクトを取得する
おもろいのはWindowsのデフォルトは今でもCP932なとこ。 IMEで打ち込んだ環境依存文字(ユニコード)はどんな文字表現になるのだろうw。

hatenablog.com→Shift_JISとUNICODE、VB.NET
.Netに読み込むときと出力するときそれぞれデコード、エンコードを掛けてる。 これってJavaVMの実装と同じ。 てことわ、IMEで入力された文字列は.Net内部でユニコードで保持され、その文字列を.Net内部から外部へのファイル入出力やTuxedo通信するそれぞれのタイミングでエンコード、デコードを掛けて解決する実装だ。

なのでSJISの電文にエンコーディングする際に環境依存文字は内部エラーになって文字化けするのだろう。VBとVC++の電文定義体に相当するコードをユニコード対応させる工数はCOBOL側と同様、膨大なものになるかも。

このクライアントの実装は現在でもVBの部品からの出力にWindows31Jのエンコーダーを掛けてSJISに変換してるそうである。 なので、いまのまま移植できれば文字コードの問題は起きないはず。

WindowsでJIS X 0213:2004の拡張文字を打ち込めないようにIMEに設定するのだとか。

マニアックな人がCygwinやMinGWで動作するGnuCOBOLとTuxedoとOracleデータベースサーバで1台のWin10で完結するシステムに挑戦するかも。(ありえねーw。

他システム連携で.CSVファイルをSJISで使っているので、すべてを一度にユニコード化することはできない。SJISとユニコードを両方喋ることができるシステムにするしかなくなる。

LANG=ja_JP.SJISとNLS_LANG=Japanese_Japan.JA16SJISで動くTuxedoのCOBOLサーバと、 LANG=ja_JP.UTF-8とNLS_LANG=Japanese_Japan.AL32UTF8で動くTuxedoのCOBOLサーバを共存。

データベースはAL16UTF16にして徐々に対応w。
qiita.com→Oracle DatabaseでのUnicode設計

Oracleの文字列型

通常はVARCHAR2またはNVARCHAR2を使うことになると思います。違いは以下のとおりです。

Charset説明
VARCHAR2DatabaseのCharset依存
NVARCHAR2Unicodeのみ(Oracleを含む大抵のDBではUTF-16でエンコードする)
やっぱ本気でやるにはUTF16のNVARCHAR2型カラムで対応することにw。
SELECT distinct(nls_charset_name(charsetid)) CHARACTERSET,
  decode(type#,1,decode(charsetform, 1, 'VARCHAR2', 2, 'NVARCHAR2', 'UNKNOWN'),
  9, decode(charsetform, 1, 'VARCHAR', 2, 'NCHAR VARYING', 'UNKNOWN'),
  96, decode(charsetform, 1, 'CHAR', 2, 'NCHAR', 'UNKNOWN'),
  112, decode(charsetform, 1, 'CLOB', 2, 'NCLOB', 'UNKNOWN')) TYPES_USED_IN
FROM sys.col$
WHERE charsetform in (1,2) and type# in (1,9,96,112)
ORDER BY characterset;

CHARACTERSET                             TYPES_USED_IN
---------------------------------------- -------------
AL16UTF16                                NCHAR
AL16UTF16                                NCLOB
AL16UTF16                                NVARCHAR2
AL32UTF8                                 CHAR
AL32UTF8                                 CLOB
AL32UTF8                                 VARCHAR2
CHARACTERSET                             TYPES_USED_IN
---------------------------------------- -------------
AL16UTF16                                NCHAR
AL16UTF16                                NCLOB
AL16UTF16                                NVARCHAR2
JA16SJIS                                 CHAR
JA16SJIS                                 CLOB
JA16SJIS                                 VARCHAR2

データベースのスキーマでは VARCHAR2 を JA16SJIS と決別させ、 JA16SJISTILDE の先の AL32UTF8 まで移行しておくべきかもw。うーむ。この辺から決断ですなぁ。

microfocus.co.jp→COBOLによるUnicodeデータ処理(2014年12月第2版)

リレーショナルデータベースの種類によってはデータベースでUnicodeに符号化されたデータを扱う手法が異なる場合があります。例えば、 Oracle データベースでは、nchar や nvarchar2 のような Unicode に対応したデータ型を使用しなくとも Unicodeをデータベースキャラ クタセットに指定することで char や varchar2 のようなデータベースキャラクタセットに応じた文字列を格納するデータ型でも Unicodeを 扱うことができます。データベースとUnicode データを授受する場合は、このようなデータベース設計も考慮する必要があります。そして COBOL プログラム側ではデータベースと授受するためのホスト変数のタイプを上で紹介しましたように正しく設計します。

hatenablog.com→OracleでSJISのデータベースの文字列カラムにUnicodeの絵文字をJavaで格納するには
「SJISのデータベースの文字列カラムにUnicodeの絵文字を格納するには、NVARCHAR2型のカラムを使います。次にJavaではシステムプロパティに-Doracle.jdbc.defaultNChar=trueを設定します。」w

cosol.jp→Oracle Database 12cのUnicode 6.1対応とEmoticons(顔文字)
要するの我々は厄所の特記事項欄に絵文字(Unicode 6.0)を打ち込める状況を目指してるわけだが、NVARCHAR2型のカラム移行もやりたくない。そしてその前にWin10のTuxedoクライアントからTuxedoサーバへの電文に少なくともUTF-8が載らないと絵文字(Unicode 6.0)以前のJIS X 0213:2004をサポートすることができないw。

Win10とのTuxedo電文はSJISの後ろにユニコードの電文を追加?w

Win10側も従来の32ビット(PE32)SJISの.EXEと32ビットのTuxedoクライアントからユニコード対応.EXEと64ビット(PE32+)のTuxedoクライアントに徐々に移行w。

「そんなことするんならCOBOL捨てます。」
などとJQに言われたので、JA16SJISをJA16SJISTILDEに変えるだけでお茶を濁すことにw。

幸い Win10側のVB.Netの.exeとCOBOLのTuxedoロードモジュールはそれぞれ業務ごとに分離されてる。
まずデータベースをNLS_LANG=Japanese_JAPAN.AL32UTF8に移行して、
その後、LANG=ja_JP.SJIS と NLS_LANG=Japanese_JAPAN.JA16SJIS と、
LANG=ja_JP.UTF-8 と NLS_LANG=Japanese_JAPAN.AL32UTF8 を共存させて、
段階的に移行して行くことを考えていたのにw。

投稿されたコメント:

コメント
コメントは無効になっています。