DB2 for i の SQL の文字列関数で DBCS 文字は正しく扱えない!? (V7R1)

DB2 for i の SQL の文字列関数で DBCS 文字は正しく扱えない!? (V5R4)」を(ふと思いついて) IBM i 7.1 で検証してみたら、いくつか変わっていたことがあったので紹介しておきたいと思います。


RIGHT/LEFT 関数を引数を 1 として実行してみると

DB2 for i の SQL の文字列関数で DBCS 文字は正しく扱えない!? (V5R4)」のいちばん最初で実行してみた SQL は↓のようなものでした。

SELECT STR,                         
       RIGHT(STR, 1)                
 FROM (SELECT 'あいうえお' AS STR 
         FROM SYSIBM/SYSDUMMY1) AS T

前回つまり V5R4 では「シフト・アウト」文字のみが 1文字として取得され、SQL クエリの結果として文字は表示されなかったのですが、7.1 では表示されるようになっています。

いくつか実験してみるとわかりますが、RIGHT/LEFT 関数の引数は文字数でのカウントになったみたいですね!
これはいい変更です。

UTF-8 へ CAST してみると

前回紹介した UTF-8 への CAST ではどうなるでしょう?

SELECT STR1208,                                                    
       RIGHT(STR1208, 1)                                           
FROM (SELECT CAST('あいうえお' AS CHAR(15) CCSID 1208) AS STR1208
         FROM SYSIBM/SYSDUMMY1) AS T

引数 1 で 1文字出てくるので、これも文字数でカウントされていることがわかりますね。V5R4 ではバイト数でのカウントで、↓と同じ結果を得るためには引数に 3 と指定する必要がありました。

もともと UTF-8 でないカラムはどうしたら

前回は紹介しませんでしたが、既存のフィールドを UTF-8 にキャストして同様に使用することができます。

EOL で使われる得意先マスター(TOKMSP)の住所カラムを部分的に取得したい場合は↓のように UTF-8 に動的に CAST して扱うことができます。

SELECT TKBANG, 
       TKNAKJ, 
       TKADR1, 
       LEFT(CAST(TKADR1 AS CHAR(15) CCSID 1208), 3) 
  FROM QEOL/TOKMSP 

↓のように文字数のカウントで取ってくることができますね。V5R4 では(文字数のカウントが 1文字あたり 3バイトになりますが)、文字列を正しくあつかうためにはこの方法を使用する必要があります。

7.1 では UTF-8 に CAST しなくても、そのまま RIGHT/LEFT 関数で文字数を指定して実行しても OK です。

SELECT TKBANG,        
       TKNAKJ,        
       TKADR1,        
       LEFT(TKADR1, 3)
  FROM QEOL/TOKMSP    

IBM i Access の「SQL スクリプトの実行」でも同様です。

SUBSTR 関数

さて、SUBSTR 関数の方はどうでしょうか?

文字列を切り出して取ってくる、という意味では LEFT 関数とかわらないわけです。↑の SQL をちょっと変更すれば使えるはずですよね。

SELECT TKBANG,        
       TKNAKJ,        
       TKADR1,        
       SUBSTR(TKADR1, 1, 3)
  FROM QEOL.TOKMSP;

文字数の指定で実行してみると、↓のようにちゃんとした文字は表示されません。。。

HEX で見てみると…

SELECT TKBANG,        
       TKNAKJ,        
       TKADR1,        
       HEX(SUBSTR(TKADR1, 1, 3)) 
  FROM QEOL.TOKMSP;   

いちばん左に "0E" が入っているのがわかりますね。

"0E" が "0F" で閉じられていないから文字化けしてしまうわけです。

これは前回の V5R4 とまったく同じ状況ですね。
UTF-8 に CAST することで解決することができます。

では UTF-8 に CAST して SUBSTR 関数を実行してみるとどうなるでしょうか。

SELECT TKBANG,        
       TKNAKJ,        
       TKADR1,        
       SUBSTR(CAST(TKADR1 AS CHAR(15) CCSID 1208), 1, 3) 
  FROM QEOL.TOKMSP;   

文字は表示されることが確認できますが、1文字のみです。
前回と同様にバイト数での指定になっているようですね。

バイト数でのカウントに切り替えて指定してみましょう。

SELECT TKBANG,        
       TKNAKJ,        
       TKADR1,        
       SUBSTR(CAST(TKADR1 AS CHAR(15) CCSID 1208), 1, 9) 
  FROM QEOL.TOKMSP;  

3 バイト X 3 文字で 9 と指定することで 3文字取得できることが確認できます。


まとめ

7.1 では RIGHT/LEFT などの関数は UTF-8 ではもちろんのこと、CCSID 1399 や 5035 などでも文字数でのカウントで指定できるようになっています。

なぜか SUBSTR 関数は今までどおり、EBCDIC の CCSID では DBCS/MBCS を正しく処理できないままです。UTF-8 に CAST して使用することで正しい結果を得ることはできるのですが、文字数のカウントではなくバイト数でのカウントになっています。

[Top Pageに戻る]

Ads by TOK2