[pgsql-jp: 32881] Re: replaceやsubstring を大量に重ねると文字が変になる?

Keiji Mitsubuchi keiji @ nwco.com
2004年 4月 29日 (木) 02:17:16 JST


三淵@NWCです。

試したわけではないので
はずしているかもしれませんが

まず、f_rtrimとf_hantozen一緒の時のみ
現象は起きているのでしょうか?
個々の関数のテストは問題無いのか?
パッチのスペースは見落としがちなので
要チェックです。

使ったことが無いのでわかりませんが
postgreSQLの関数substring(),length()は
ちゃんと、ダブルバイトで帰ってくるのでしょうか?
length(" ") = 1 or 2 ?
もし、バイト数で帰ってくるのであれば
全角のスペースがはいっていると
おかしくなる可能性がありますよね。

ご参考になれば幸いです。

----- Original Message ----- 
From: "minoyama" <minoyama @ t-tsc.co.jp>
To: <pgsql-jp @ ml.postgresql.jp>
Sent: Thursday, April 29, 2004 12:41 AM
Subject: [pgsql-jp: 32880] replaceやsubstring を大量に重ねると文字が変になる
?


> postgres初心者のminoyamaと申します。
> 皆様のお知恵をお貸しください。
>
> バージョン 7.3.4 を Redhat Linux ES2.1上で使っています。
> DBのエンコーディング・OSの文字コードは、EUC_JPです。
>
>
> 次のような後方ブランク(半角・全角とも)を取り除く関数を作りました。
> 単純に、引数の後ろから文字を1文字ずつチェックし、ブランクであれば、
> 取り除く処理です。
>
> create function f_rtrim(varchar(256)) returns varchar(256) as '
> declare
>
>   sWork varchar(500);
>   aLen int4;
>   sMoji varchar(2);
>
> begin
>   sWork := $1;
>   loop
>     aLen := length(sWork);
>     sMoji := substring(sWork,aLen,1);
>     if sMoji = '' '' or sMoji = '' '' then
>       sWork := substring(sWork,1,aLen-1);
>     else
>       exit;
>     end if;
>   end loop;
>   return sWork;
> end;
> 'language 'plpgsql';
>
>
>
>
> 次のような、半角カタカナを全角カタカナに変換する関数を
> つくりました。
> replace関数をつかって、半角アなら全角アに、半角イなら全角イに
> という処理をひたすら重ねています。
>
> [半角の]と書いているのは、本MLルールで半角カタカナが使えない
> ため、[半角の]ア等の表現をしていますが、実際には、本当に半角のア
> が記載されているものとして呼んでください。
>
> create or replace function f_hantozen(varchar(256))
> returns varchar(256) as '
> declare
>   sWork varchar(500);
>
> begin
>
>   sWork := $1;
>
>     sWork := replace(replace(replace(replace(replace(replace
>              (replace(replace(replace(replace(replace(replace
>              (replace(replace(replace(replace(replace(replace
>              (replace(replace(replace(replace(replace(replace
>              (replace(replace(replace(replace(replace(replace
>              (replace(replace(replace(replace(replace(replace
>              (replace(replace(replace(replace(replace(replace
>              (replace(replace(replace(replace(replace(replace
>              (replace(replace(replace(replace(replace(replace
>              (replace(replace(replace(replace(replace(replace
>              (replace(replace(replace(replace(replace(replace
>              (replace(replace(replace(replace(replace(replace
>              (replace(replace(replace(replace(replace(replace
>              (replace(replace(replace(replace(replace(replace
>              (replace(replace(sWork, ''ガ'', ''ガ'')
>              , ''[半角の]ギ'', ''ギ''), ''[半角の]グ'', ''グ'')
>              , ''[半角の]ゲ'', ''ゲ''), ''[半角の]ゴ'', ''ゴ'')
>              , ''[半角の]ザ'', ''ザ''), ''[半角の]ジ'', ''ジ'')
>              , ''[半角の]ズ'', ''ズ''), ''[半角の]ゼ'', ''ゼ'')
>              , ''[半角の]ゾ'', ''ゾ''), ''[半角の]ダ'', ''ダ'')
>              , ''[半角の]ヂ'', ''ヂ''), ''[半角の]ヅ'', ''ヅ'')
>              , ''[半角の]デ'', ''デ''), ''[半角の]ド'', ''ド'')
>              , ''[半角の]バ'', ''バ''), ''[半角の]パ'', ''パ'')
>              , ''[半角の]ビ'', ''ビ''), ''[半角の]ピ'', ''ピ'')
>              , ''[半角の]ブ'', ''ブ''), ''[半角の]プ'', ''プ'')
>              , ''[半角の]ベ'', ''ベ''), ''[半角の]ペ'', ''ペ'')
>              , ''[半角の]ボ'', ''ボ''), ''[半角の]ポ'', ''ポ'')
>              , ''[半角の]ヴ'', ''ヴ''), ''[半角の]ァ'', ''ァ'')
>              , ''[半角の]ア'', ''ア''), ''[半角の]ィ'', ''ィ'')
>              , ''[半角の]イ'', ''イ''), ''[半角の]ゥ'', ''ゥ'')
>              , ''[半角の]ウ'', ''ウ''), ''[半角の]ェ'', ''ェ'')
>              , ''[半角の]エ'', ''エ''), ''[半角の]ォ'', ''ォ'')
>              , ''[半角の]オ'', ''オ''), ''[半角の]カ'', ''カ'')
>              , ''[半角の]キ'', ''キ''), ''[半角の]ク'', ''ク'')
>              , ''[半角の]ケ'', ''ケ''), ''[半角の]コ'', ''コ'')
>              , ''[半角の]サ'', ''サ''), ''[半角の]シ'', ''シ'')
>              , ''[半角の]ス'', ''ス''), ''[半角の]セ'', ''セ'')
>              , ''[半角の]ソ'', ''ソ''), ''[半角の]タ'', ''タ'')
>              , ''[半角の]チ'', ''チ''), ''[半角の]ッ'', ''ッ'')
>              , ''[半角の]ツ'', ''ツ''), ''[半角の]テ'', ''テ'')
>              , ''[半角の]ト'', ''ト''), ''[半角の]ナ'', ''ナ'')
>              , ''[半角の]ニ'', ''ニ''), ''[半角の]ヌ'', ''ヌ'')
>              , ''[半角の]ネ'', ''ネ''), ''[半角の]ノ'', ''ノ'')
>              , ''[半角の]ハ'', ''ハ''), ''[半角の]ヒ'', ''ヒ'')
>              , ''[半角の]フ'', ''フ''), ''[半角の]ヘ'', ''ヘ'')
>              , ''[半角の]ホ'', ''ホ''), ''[半角の]マ'', ''マ'')
>              , ''[半角の]ミ'', ''ミ''), ''[半角の]ム'', ''ム'')
>              , ''[半角の]メ'', ''メ''), ''[半角の]モ'', ''モ'')
>              , ''[半角の]ャ'', ''ャ''), ''[半角の]ヤ'', ''ヤ'')
>              , ''[半角の]ュ'', ''ュ''), ''[半角の]ユ'', ''ユ'')
>              , ''[半角の]ョ'', ''ョ''), ''[半角の]ヨ'', ''ヨ'')
>              , ''[半角の]ラ'', ''ラ''), ''[半角の]リ'', ''リ'')
>              , ''[半角の]ル'', ''ル''), ''[半角の]レ'', ''レ'')
>              , ''[半角の]ロ'', ''ロ''), ''[半角の]ワ'', ''ワ'')
>              , ''[半角の]ヲ'', ''ヲ''), ''[半角の]ン'', ''ン'')
>              , ''[半角の]ー'', ''ー''), ''[半角の]、'', ''、'')
>              , ''[半角の]。'', ''。''), ''[半角の]「'', ''「'')
>              , ''[半角の]」'', ''」'');
>
>   return sWork;
> end;
> 'language 'plpgsql';
>
>
> これら2つの関数を重ね合わせて、半角−>全角変換しながら、
> 後方ブランクを取り除くSQLを次のように作り、psqlから実行しました。
> select '''' || col1 || ''''
>      , '''' || f_hantozen(f_rtrim(col1)) || ''''
> from tbl1
> order by col1;
>
> すると、
>
>             col1                |         ?column?
> --------------------------------+--------------------------
>  'ミツビシ               '      | 'ミツビシ'
>  'ミツビシ               '      | 'ミツビシ'
>  'ミツビシ               '      | 'ミツビシ'
>  'ミツビシ               '      | 'ミツビシ'
>  'ミツビシ               '      | 'ミツビシウ'  <−−
>  'ミツビシ               '      | 'ミツビシウ'  <−−
>  'ミツビシ               '      | 'ミツビシウ'  <−−
>  'ミツビシ               '      | 'ミツビシウ'  <−−
>  'ミツビシ               '      | 'ミツビシウ'  <−−
>  'メルセデスベンツ          '   | 'メルセデスベンツ'
>  'メルセデスベンツ          '   | 'メルセデスベンツ'
>  'メルセデスベンツ          '   | 'メルセデスベンツウ'  <−−
>  'メルセデスベンツ          '   | 'メルセデスベンツ'
>  'メルセデスベンツ          '   | 'メルセデスベンツウ'  <−−
>
> のような答えが返ってきます。
> 問題なのは、"<−−"を付けた行なのですが、ウという文字が最後について
> きます。
> しかも、同じ、「メルセデスベンツ          」という文字を同じ関数に
> 通しているのに。
> また、単純に、
> select f_hantozen(f_rtrim('メルセデスベンツ          '))
> とやっても、決して、「メルセデスベンツウ」とはならないのに、
> テーブルからselectした場合のみ、不特定多数の行でこの「ウ」が
> うしろについてきます。
>
> また、f_hantozenを単体で試した場合や、f_rtrimを単体で試した
> 場合にも問題は発生しません。
>
> この原因は何なのでしょうか?
> また、回避方法はあるのでしょうか?
>
> 原因、対策について、皆様のお知恵をお貸し頂きたく。
> よろしく御願いします。
>
>
>
>
>




pgsql-jp メーリングリストの案内