- PR -

DataTableで半角空白と全角空白を区別させるには?

投稿者投稿内容
常連さん
会議室デビュー日: 2004/10/27
投稿数: 21
投稿日時: 2007-02-17 02:28
いつもお世話になっております。
今回教えていただきたいのはDataTableで主キー制約のついた列に対して
半角空白が設定された行と、全角空白が設定された行を登録する方法です。
以下のようなコードを実装したいと思っています。
コード:
	DataTable dtSample = new DataTable();
	dtSample.Columns.Add(new DataColumn("Column1", typeof (string)));

	// 制約を登録
	dtSample.Constraints.Add("PrimaryKey", dtSample.Columns[0], true);

	// 半角空白を設定
	dtSample.Rows.Add(new object[] {" "});

	// 全角空白を設定
	dtSample.Rows.Add(new object[] {" "});



実際にこのコードを実行すると空白のみで構成された文字列の場合は
半角空白と全角空白は同一の文字列として認識されるようで
制約違反が発生してしまいます。
一文字以上の空白以外の値が存在する文字列であればDataTabel.CaseSensitiveプロパティを
trueに設定することによって半角空白と全角空白を別々として認識をしてくれるのですが
空白のみの文字列の場合は同一の値としてしまいます。
どのようにすれば半角空白と全角空白を区別させることが出来るのでしょうか?
方法がありましたらご教授していただけると幸いです。
よろしくお願いします。

開発環境
WindowsXP Pro SP2
Visual Studio 2005
platini
大ベテラン
会議室デビュー日: 2002/12/03
投稿数: 193
投稿日時: 2007-02-17 10:56
コーディングそのものは恐らく回避する方法があると思うが、
PrimaryKeyに半角スペースとか全角スペースで区別する
発想(設計)はやめたほうがよいかと。。。

どうみてもまともな設計だとは思えません。

それを承知で、恐らく聞いているとは思うし、
直接的な回答でないレスを返すなよ!と言いたいと思うが、
コーディング回避方法が見つかっても、それで是とすべき内容ではないかと思います。

常連さん
会議室デビュー日: 2004/10/27
投稿数: 21
投稿日時: 2007-02-17 13:37
ご意見ありがとうございます。
確かにplatiniさんのおっしゃるとおりだと思いますし、
業務ルール上もありえないとは思うのですが、DB上データとして
存在させられる以上、アプリ側でも対応させておくべきかと思っています。
実際、昨日まで私自身もそんなデータはありえないと思っていて製造の段階では
この問題を全然考慮していませんでした。
ですが、昨日同僚がこの部分のテストをしていて間違って作ったデータを
使ってみたらこの問題が浮上してしまって困っている状態です。
七味唐辛子
ぬし
会議室デビュー日: 2001/12/25
投稿数: 660
投稿日時: 2007-02-17 14:37
通常なら? 前後の空白をTRIMして登録しますが!

空白に意味があるんだよ!と言われたたら 返す言葉もありません
せん
ぬし
会議室デビュー日: 2002/03/04
投稿数: 397
投稿日時: 2007-02-17 14:43
業務ルール上も、アプリケーションロジック的にもあり得ないデータなので
あれば、それは入るはずの無いデータなわけで。
それを登録できるようアプリケーション側で対応するのはどうなのかな?
とおもいます。
逆にアプリケーション側でいいように処理してしまうことで、仕様バグを
残してしまう事にもなりかねません。

いったん仕様策定者やお客さんと会話した方がよろしいかとおもうんですけどね。

という、そんなこたぁ百も承知よ!なコメントしかできません。すいません。
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2007-02-18 01:52
引用:

怜さんの書き込み (2007-02-17 13:37) より:

使ってみたらこの問題が浮上してしまって困っている状態です。


憶測の話で申し訳ないのですが、これは仕様なのかもしれません。

「PrimaryKey において、全角と半角スペースを別視させることを是とした前提の処理をすべきでない」という意見は、このスレに投稿している全ての人(僕やスレ主さんを含めた)が唱えている訳ですし、そういう意味では、現在の動作で良いと思いますし、変える必要も無いかと思う訳です。

「データベースに、このようなデータが存在しうる可能性がある以上、これを別視させる方法を考えよう」ではなく「アプリケーション側は、データベースにそのようなデータを登録させないような設計でなければならない」と考える方が正しいと思いますし、仮にそれを許すアプリケーションが存在した場合、そのアプリケーションが悪いと割り切って良いように思います。
_________________
R・田中一郎 -  R.Tanaka.Ichiro’s Blog
常連さん
会議室デビュー日: 2004/10/27
投稿数: 21
投稿日時: 2007-02-18 02:56
To 七味唐辛子さん
仰るとおりアプリを通して追加されたデータであればTrimをかけますので
空白のデータはDB上に存在しません。
実際問題になっている列は数値データ(でもDB上はChar型)が入ります。
今回問題浮上の元になったのはテスト用にDBに直接手入力して作った
データでした。
テストデータ自体が間違っていたと言う落ちではあるんですが、私の予測では
ちゃんと半角/全角を区別するはずだと思っていたのですが、そうならなかった
ので悩んでいました。
もしDataTableやDataColumnのプロパティを設定して半角/全角を区別できるように
なるのであれば、存在しないデータに対する対策になってしまいますが
実装しておくべきかと思っていました。

To せんさん
業務ルール上は存在しないはずなので、この問題に対する対処については
本日お客様にメールにて問い合わせてみました。
早ければ明日には返事がもらえるかもしれませんので、その内容によって
もう一度仕様などについて話し合ってみます。

To R・田中一郎さん
確かに「PrimaryKey において、全角と半角スペースを別視させることを是とした前提の
処理をすべきでない」という考えが正しいですね。
もしこの問題に対してお客様から半角/全角を区別しろと言われた場合はDataTableを
使わないで処理する方向で対処するようにしてみます。

[ メッセージ編集済み 編集者: 怜 編集日時 2007-02-18 04:34 ]
dotnetmemo
常連さん
会議室デビュー日: 2006/04/29
投稿数: 24
投稿日時: 2007-02-18 10:56
こんにちは。
あくまでも推測ですが参考までに

どうもString型のカラムの比較では、文末の空白(半角・全角)を除いて比較するようです。したがって、"A "と"A "も同じになります。逆に" A"と" A"は同じになりません。
ただし、後者はDataTableのCaseSensitiveをtrueに設定している前提です。

ちなみに、string型をやめてobject型のカラムにするという力技はなくもありませんが、他の影響度を考えるとお勧めできないと思います。

dtSample.Columns.Add(new DataColumn("Column1", typeof(object)));

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