The road to C# master trapemiya

C#を中心に、.NETの話題を取り上げます。

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  256  : 記事  1  : コメント  10763  : トラックバック  30

ニュース

Since 2005年10月26日

わんくま同盟

わんくま同盟

Microsoft MVP


Visual Developer - Visual C#

記事カテゴリ

書庫

日記カテゴリ

.NET2.0になってからTableAdapterというのもが増えた。これはこれで非常に便利なものである。しかし、問題がある。動的にSQL文を発行したい場合だ。特に検索系において、動的にwhere句を変えたい場合、どうやれば良いのだろうか?

これについては2つあると思う。一つは、partial classでパブリックなCommandCollectionを定義して、それをプログラムから利用する方法。もう一つは、Fillをオーバーライドする方法だ。しかし、いずれにしても弱点がある。CommandCollection[0]という風に、インデックスでアクセスする方法でしか、SqlCommandが得られないということである。これはあまりにも気持ち悪い。しかも、インデックスの順番なんか保障されていない。
なので、上の二つの方法を採用することはあきらめた。

では、どのようにしてアクセスしようか?

結果的には、全てストアドプロシージャで対応することにした。SQL文やwhere句の動的な作成も、全てストアドプロシージャで行うことにした。

元々、ストアドプロシージャを使っておけばいろいろと気にしなくても良い。プログラムでSQL文を組み立てる場合、例えば'90年のように、「'」を含む文字列を入力されたらどうなるだろう? それだけで、SQL文は動かなくなってしまう。この点、ストアドプロシージャのパラメータで渡しておけば安心だ。

というわけで、CommandCollection[0]とはおさらばだ。

#それにしてもなぜTableAdapterはCommandCollectionを使いやすく公開していないのだろうか?ついでにDataAdapterもである。Fillはvirtualなのに、DataAdapterはprivateで定義してある。FillをオーバーライドしたらDataAdaperにアクセスできれば便利なんで、DataAdapterはprotectedで定義して欲しかった。もっとも、partial classでDataAdapterをpublicで公開してあげればFill内で使えるんだけど、手間なんですよね。

#何年か前にわんくま中さんが、何でもストアドって言ってたけど、徐々に身にしみてくるなぁ。

投稿日時 : 2006年8月16日 19:04

コメント

# re: CommandCollection[0]とはおさらばだ。 2006/08/16 23:49 とおりすがり
これじゃ、駄目なんですよね。。

http://www.atmarkit.co.jp/fdotnet/bookpreview/vs2005webapp_07/vs2005webapp_07_04.html

# re: CommandCollection[0]とはおさらばだ。 2006/08/17 2:08 中博俊
select *
from [T-ポスト]
where ポストID = case when @ポストID is not null then @ポストID else ポストID end

こんな感じで出来ますよ。

# re: CommandCollection[0]とはおさらばだ。 2006/08/17 11:46 trapemiya
>>とおりすがりさん
ご紹介された本、持っているんですが、ちゃんと読んでませんでした。(^^;
この発想は思いつきませんでした。確かに、Fillのような関数を自分で定義しちゃえばなんでもできますね。ウイザードで生成されたFillをなんとかいじって目的を達成しようとしていたわけですが、そこから離れればよかったんですね。こういう方法もあるということで大変勉強になりました。本文に書いたことに加えて、第3の方法ですね。

>>中さん
このSQLはストアドプロシージャ内でもよく使うんですが、
select *
from [T-ポスト]
where ポストID <> case when @ポストID is not null then @ポストID else ポストID end
のように、<>の時にこまっちゃうんです。

# re: CommandCollection[0]とはおさらばだ。 2006/08/17 16:54 THREE-ONE
<>の場合はこうすれば良いのではないでしょうか?
select *
from [T-ポスト]
where
case when @ポストID is not null then ポストID else 1 end
<> case when @ポストID is not null then @ポストID else 0 end
= に直したい場合は 1 = 1 になるようにしてやればいいですし、修正らくちん

多少冗長になりますし、ポストIDの型にあわせてあげなければなりませんが


# re: CommandCollection[0]とはおさらばだ。 2006/08/17 18:13 黒龍
> これじゃ、駄目なんですよね。。

> http://www.atmarkit.co.jp/fdotnet/bookpreview/vs2005webapp_07/vs2005webapp_07_04.html

ずっと気になってたので横槍。この記事ではだめって書いてますけどTOP句ってパラメータ化できますよね?
SELECT DISTINCT TOP (@NumberOfCases)
見たいにすれば・・・。なもんでこの本やらはスルーしてましたが。

CommandCollectionの公開に関しては私もそう思います。タイムアウトの設定でいちいちPertialかかないといけないので・・・。

# re: CommandCollection[0]とはおさらばだ。 2006/08/17 21:59 trapemiya
>>THREE-ONEさん
お~、SQLインジェクションを逆手に取ったような方法で、おもしろいですね。(^^
確かにこれでいけると思いますが、おっしゃるようにちょっと冗長度が高いですよね。でも、where句の条件式がこのように一つだけなら、コーディングが楽でいいかもしれません。

>>黒龍さん
ストアドプロシージャではTOP句はパラメータにできないのはあきらかなんですが、TableAdapterでは使えるのかもしれませんね。明日にでも試してみます。

# re: CommandCollection[0]とはおさらばだ。 2006/08/18 14:19 trapemiya
>>黒龍さん
TableAdapterでTOP句はパラメータにできました。しかし、パラメータをかっこでくくる必要がありました。なぜ、かっこでくくるとできるんだろう?それにしても、よく見つけましたね。
調子に乗って、where (@wherewk) みたいに書いてみたんですが、ダメでした。Orz

# re: CommandCollection[0]とはおさらばだ。 2006/10/16 16:05 trapemiya
>プログラムでSQL文を組み立てる場合、例えば'90年のように、「'」を含む文字列を入力されたらどうなるだろう? それだけで、SQL文は動かなくなってしまう。

上でこんなこと言ってましたが、SQL文を組み立てる場合でも、パラメータオブジェクトを使えば大丈夫です。言葉足らずでした。m(_ _)m

# Test, just a test 2022/12/13 10:39 www.candipharm.com/
canadian customs pills vitamins http://candipharm.com/#

Post Feedback

タイトル
名前
Url:
コメント