全角文字と半角文字が入り乱れている文字列を分割し、2つの変数に格納する際に、泣き別れが発生しないように対応を変えて分割をしたいと考えています。
前提として、自分の環境だと全角文字は1文字に対して3バイト扱いとなります。
下記のコードでは文字列'あああいいいaa'(全角文字6文字×3 = 18 + 半角2文字で合計20バイト)の文字を最大10バイトの変数2つに分割しようとしています。
これだと、4文字目の「い」が9~11バイトにかかっており、10バイトずつ分割した場合に泣き別れが発生して、
str1の最後に半角スペース1つ、str2の最初に半角スペース2つという形で「い」が置き換えられてしまいます。
PLSQL
1DECLARE 2str0 VARCHAR2(20); 3str1 VARCHAR2(10); 4str2 VARCHAR2(10); 5BEGIN 6 str0 := 'あああいいいaa'; 7 8 IF LENGTHB(str0) > 10 THEN 9 str1 := str0; 10 ELSE 11 str1 := SUBSTRB(str0,1,10); 12 str2 := SUBSTRB(str0,11); 13 END; 14 15 DBMS_OUTPUT.PUT_LINE(str1); 16 DBMS_OUTPUT.PUT_LINE(str2); 17END;
求める結果としては、上記の場合だと
「あああ」までをstr1に格納し、
「いいいa」までをstr2に格納し、入りきらない最後の「a」は格納しないといった処理を行いたいです。
NLS_LENGTH_SEMANTICS により VARCHAR2(10) に格納できる文字数が変わります。
BYTE だと 10バイト、CHAR だと10文字です。(標準は BYTE)
また、ひと文字の長さは NLS_CHARACTERSET で決まり、標準の AL32UTF8 だと
SELECT LENGTHB('A'), LENGTHB('Ω'), LENGTHB('漢'), LENGTHB('𩸽') FROM DUAL
の結果は 1,2,3,4 になります。
本題については、LENGTHC で文字長を求め、SUBSTRC で一文字ずつ切り出し、LENGTHB でバイト数をチェックすることになります。
それでも異体字や結合文字は泣き別れしてしまうので、どこかで割りきる必要がありそうです。
回答してからコメントがあるのに気づきました。おんなじこと書いてましたね。

回答1件
あなたの回答
tips
プレビュー