2017年3月
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
無料ブログはココログ

« のみでん広場 | トップページ | すずめばちのすがあります »

2008.07.08

またまたDB2ではまった

またまたDB2でCSVファイル出力をしようとしたときの話です。


ある条件では空白を固定で何文字か出したかったので、

  CASE WHEN ROW1=1 THEN ROW2 ELSE SPACE(2) END

みたいなSELECT句を書いていました(ここでROW2はCHAR(2)の列です)。
すると、CSVファイルに出力するときに、「254バイトを超えている」という警告が出るのです。
ROW2を出力しても2バイトだし、半角スペース2つでも2バイトなので、どう考えても254バイトを超えているはずがありません。
実際に出力されたCSVファイルを見てもそんなに長い文字列は出力されていません。ちゃんと2バイトの空白が出力されています。
ちなみにDB2の固定長文字列列の最大長は254バイトですので、このあたりの絡みで警告が出ているようです。

マニュアルを見てみると、SPACE関数の戻り値の型はVARCHAR(4000)になるのだそうです。
4000というのが254を超えているからということで警告が出るように思えます。

しかし、実際に出力されているのは2バイトなのに、254バイトを超えているという警告が出るのはちょっと困ります。
出力されるCSVファイルには期待通りのものが出力されているので問題ないのですが、テスト結果の報告には出力されたCSVファイルだけでなく実行した証拠として実行時のメッセージなども提出しないといけないのです。なので、警告が出ているというのはあまり好ましいものではありません。
結局今回も(前回のNULLに続いて)CASTのお世話になることになりました。

  CASE WHEN ROW1=1 THEN ROW2
    ELSE CAST(SPACE(2) AS CHAR(2)) END

とすれば警告は出なくなります。
しかし、2バイトだと言っているのに254バイトを超えていると言われるのはやはり納得いきませんね。

もっと簡単に文字列定数で '  ' とすれば警告は出なくなりますが、何十バイトとかになってくるとやっぱりSPACE関数を使いたいですよね。
それに、同じ事はLEFTやRIGHTの関数にも言えるのです。

  LEFT('ABCDE', 3)

の戻りもVARCHAR(4000)なので、同じ警告が出てしまいます。
3バイトにしたいからLEFT関数で3バイトだけ取ってきているのに……

ただ、SUBSTR関数だけはちょっと様子が違います。

  SUBSTR('ABCDE', 2, 3)

は、戻り値の型が戻り値のサイズ(この場合はCHAR(3))になるのです(但し254バイト以内の場合)。
LEFTやRIGHTというのは特殊な条件のSUBSTRと考えることも出来るので、ますます納得いかない仕様です。

なお、CSV出力を行わずにSQLだけを実行した場合は警告は出ません。
また、INSERT INTOでテーブルに追加する場合にも警告は出ません。もちろん、格納先のサイズが小さい場合は警告どころかエラーになりますけど、それはごく普通の動作でしょう。

なぜCSV出力のときにだけ、こんなありがたくない特別扱いになっているのでしょうか。

« のみでん広場 | トップページ | すずめばちのすがあります »

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/39755/41778484

この記事へのトラックバック一覧です: またまたDB2ではまった:

« のみでん広場 | トップページ | すずめばちのすがあります »

にほんブログ村

Amazon.co.jp