[pgsql-jp: 32880] replaceやsubstringを大量に重ねると文字が変になる?
minoyama
minoyama @ t-tsc.co.jp
2004年 4月 29日 (木) 00:41:09 JST
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 メーリングリストの案内