rm /blog

IT系技術職のおっさんがIT技術とかライブとか日常とか雑多に語るブログです。* 本ブログに書かれている内容は個人の意見・感想であり、特定の組織に属するものではありません。/All opinions are my own.*

【Oracle】NUL(U+0000)の後ろには文字列結合できない

OracleでNUL(UnicodeでいうとU+0000、制御コード)の後ろに文字列結合すると、結合した文字列が消滅するらしい。
要するにNULの後ろに文字をくっつけることができない。
そういうもんなのか?
なんとなく、まあ、気持ちはわからんでもないけどそういうこと勝手にやるなよなあ~って思う。
俺だけ?


 

 
例えば以下のようなSQLで文字列結合してみる


select 'ABCDE' || chr(0) || 'FGHIJ' from dual


と、返ってくる値は「ABCDE」になる。
つまり、後ろにくっつけようとした「FGHIJ」がくっつかない。
これに限らず、chr(0)の後ろにくっつける文字列は悉く消滅し、文字列結合が成立しない。

ただ、まあ、「じゃあどうすればよかったの?」って言われると確かにちょっと困る。
気持ち的には「ABCDEFGHIJ」で(chr(0)を完全無視して有効な文字だけくっつけて)返ってきてくれるとありがたいのだが
意図的に書いてあるchr(0)をシカトするのもいかがなもんかと思うし、
そもそも”有効な”ってなんやねんどう定義するねんっていう気もする。
だから要するに「ABCDE[nul]FGHIJ」で返ってきてくれれば
それでもう問題ないのである。(ABCDEの後ろ、FGHIJの前にNUL(U+0000)のコード)をそのままくっつけて出してくれればそれでいい)

ひょっとしてNULの後ろに文字くっつけられないっていう世界標準的な仕様か?
と思ってJavaで組んでみたけどそういうことは起きない(ちゃんとNULがそのまま出力される)


import java.io.*; public class CharPlusTest { private static final String nul = new String(new byte[]{0}); private static final String space = new String(new byte[]{0x20}); private static final String a = new String(new byte[]{0x61}); private static final String ENCODING_UTF8 = "UTF-8"; public static void main(String[] args) { try { File outputFile1 = new File("01_nul_plus.txt"); String outputStr1 = a + space + nul + space + a; execMain(outputFile1 , outputStr1); File outputFile2 = new File("02_non_nul_plus.txt"); String outputStr2 = a + space + space + a; execMain(outputFile2 , outputStr2); } catch(Throwable e) { e.printStackTrace(); } } private static void execMain(File outputFile,String outputStr) throws Throwable { BufferedWriter bw = null; try { bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile),ENCODING_UTF8)); bw.write(outputStr); bw.newLine(); bw.flush(); } catch(Throwable e) { e.printStackTrace(); } finally { if (bw != null) { bw.close(); } } } }


このJavaを実行すると「01_nul_plus.txt」と「02_non_nul_plus.txt」という2つのテキストファイルが出来上がる。
「01_nul_plus.txt」には"a"+" "(半角スぺース)+NUL(U+0000)+" "(半角スペース)+"a"という文字列
「02_non_nul_plus.txt」には"a"+" "(半角スぺース)+" "(半角スぺース)+"a"という文字列
を結合して(Stringにして+でくっつけ)ファイルに出力する。
要するに「01_nul_plus.txt」にNULを指示して出力している。
で、こっちはNULがNULのまま、かつ後ろの文字列(半角スペースと"a")もちゃんとくっついて出力される。

やっぱりOracleだけっぽいな。
勝手なことするなやって感じがしているのである。