- PR -

SQLサーバーのtext型の列でsubstringを使用する場合

1
投稿者投稿内容
ケイ
大ベテラン
会議室デビュー日: 2004/04/20
投稿数: 100
投稿日時: 2004-04-26 11:21
現在SQLサーバーとVB6で開発を行っています。

Create table Tes(T1 Text, T2 Int)で
テーブルを作成したとして、

Select文でデータを取得する場合に、
text型にSubstringを使用すると、バイト計算になりますよね?

その場合、取得する始めの文字が全角の場合、半角分取得してしまい、
正しい文字で取得できません。

T1のデータが「江藤・高見沢」と「大久保・木津」だった場合
select substring(T1,9,17) From Tes
を実行した場合、

「江藤・高見沢」から取得した値が「ウ」
「小塚・木津」から取得した値が「リ津」
となります。

なので、substring(T1,9,17)を実行して、取得した始めの文字が
全角だったものが半角として取得された値だった場合、
全角で取得するようにしたいです。

その為、
select (case whern left(substring(T1,9,17),1) = 'リ' then
substring(T1,8,17)
else
substring(T1,9,17)
end) From Tes

として取得した半角が'リ'だったら取得するバイト位置をずらそうかとも思いましたが、
全角だったものを半角で切り取った場合に取得する値がすべて'リ'になる訳ではないし、
本当に半角で'リ'だった場合の見分けがつきません。

何かいいアイディア等ありましたら、
教えて下さい。


かめたろ
ぬし
会議室デビュー日: 2003/03/20
投稿数: 255
投稿日時: 2004-04-26 12:05
Transact-SQLリファレンス より引用:
「注 SUBSTRING が text 型データに対して使用される場合、start と length はバイト数を指定します。このため、漢字などの DBCS データでは、結果の先頭や最後で文字が分割されることがあります。この動作は、READTEXT が DBCS を処理する場合の動作と一致しています。ただし、望まない結果が得られる場合もあるので、DBCS 文字に対しては text 型ではなく ntext 型を使用することをお勧めします。」

とあるので、今回のケースでは Text型ではなくntext型を使用すべきなのでは。あるいはCONVERT関数でntext型に型変換???。
また「・」で文字列を分割しているように見えるのでCHARINDEX関数を使えば分割位置がわかります。
ケイ
大ベテラン
会議室デビュー日: 2004/04/20
投稿数: 100
投稿日時: 2004-04-26 14:33
返信ありがとうございます。

すみません。使用していたデータが悪かったようです。

TesテーブルのT1列に登録されるデータは、
必ずしも「・」がついている訳ではなく、
またデータは半角と全角が混在するデータになります。

T1は2つに分けて取得する。
またその際、1つ8バイトで取得したい為、
「テスト123」なら「てすと12」と「3」に分けて取得。
「テスト取得」なら「テスト」と「取得」に分けて取得
「テスト1文字」なら「テスト1」と「文字」に分けて取得

のようにしたいのです。
それでsubstringでバイト数で取得しようと思い、
text型にしました。

ntext型にしてしまうと、substringは文字数でしか取得できないので、
使用していませんでした。

特にtext型にはこだわってはいないです。
列に登録されている文字が半角全角混在で、
2つ(8バイトごと)に取得する場合に、
select文で取得する方法が他に思いうかばなかっただけです。

他の方法でもよろしいので、何かアイディアがある方は
教えて下さい。
永井和彦
ぬし
会議室デビュー日: 2002/07/03
投稿数: 276
お住まい・勤務地: 東京都
投稿日時: 2004-04-26 15:59
引用:

T1は2つに分けて取得する。
またその際、1つ8バイトで取得したい為、
「テスト123」なら「てすと12」と「3」に分けて取得。
「テスト取得」なら「テスト」と「取得」に分けて取得
「テスト1文字」なら「テスト1」と「文字」に分けて取得

のようにしたいのです。



上記のままの仕様ですと完全にお手上げなのですが、例の2つ目は……
「テスト取得」なら「テスト取」と「得」に分けて取得
……ですよね?

ところで、絶対SQL上で分割処理をやらなければいけないでしょうか?
普通にSelectしてからプログラム側で分割は不可だったりしますか?
ケイ
大ベテラン
会議室デビュー日: 2004/04/20
投稿数: 100
投稿日時: 2004-04-26 19:36
>上記のままの仕様ですと完全にお手上げなのですが、例の2つ目は……
>「テスト取得」なら「テスト取」と「得」に分けて取得
>……ですよね?
すみません。間違えてました。
その通りです。

今まではプログラムで処理していましたが、
切り分けるべき個数が可変の為、select分で処理をした方が、早いかと思いました。
※最大(99)*(人数分)の個数分を切り分け無ければいけないのです。

比較はしなければいけませんが、
比較する為にもselect文のみでできるように作成しようとしています。
ケイ
大ベテラン
会議室デビュー日: 2004/04/20
投稿数: 100
投稿日時: 2004-04-27 09:23
一応substringを使用して取得する事ができました。

select (case when
datalength(substring(T1,1,8)) < 8 then
substring(T1,8,8)
else
substring(T1,9,8)
end) From Tes

取得した文字をバイト数で取得し、
次に取得するバイト位置を変える事で一応目的の通りに
取得する事ができました。

[ メッセージ編集済み 編集者: ケイ 編集日時 2004-04-27 09:28 ]
1

スキルアップ/キャリアアップ(JOB@IT)