C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: OleDBでSQLに変数を渡す方法


(過去ログ 92 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■55098 / inTopicNo.1)  OleDBでSQLに変数を渡す方法
  
□投稿者/ akira (14回)-(2010/11/16(Tue) 22:20:30)

分類:[ASP.NET (VB)] 

VWD2008とDBにMS-Access2003を利用し、Webアプリの認証機能を↓のページを参考に作成し
ています。(SQL ServerをMS-Accessに変更)
http://www.atmarkit.co.jp/fdotnet/dotnettips/147aspusrdb/aspusrdb.html
OleDBで扱うSQLのパラメータに変数で渡す方法がわからなくて困っております。
アドバイス頂けると助かります。

Dim objCom As New OleDbCommand("SELECT * FROM usr WHERE uid=@uid AND passwd=@passwd", objDb)
objCom.Parameters.Add("@uid", OleDbType.VarWChar, 50)
objCom.Parameters("@uid").Value = txtUsr.Text            
objCom.Parameters.Add("@passwd", OleDbType.VarWChar, 50)
objCom.Parameters("@passwd").Value = txtPass.Text

の様に@uid、@passwdの順に変数を設定するとプログラムは正しく動くのですが、

Dim objCom As New OleDbCommand("SELECT * FROM usr WHERE uid=@uid AND passwd=@passwd", objDb)
objCom.Parameters.Add("@passwd", OleDbType.VarWChar, 50)
objCom.Parameters("@passwd").Value = txtPass.Text
objCom.Parameters.Add("@uid", OleDbType.VarWChar, 50)
objCom.Parameters("@uid").Value = txtUsr.Text            

と@passwd、@uidの順に変数を設定するとプログラムが正しく動いてくれません。
(「正しいユーザID、パスワードを入力してください」のメッセージルーチンに入ってしまう。)
安定して稼働する、SQLのパラメータを変数で設定する方法をアドバイス頂けると助か
ります。よろしくお願いします。

引用返信 編集キー/
■55099 / inTopicNo.2)  Re[1]: OleDBでSQLに変数を渡す方法
□投稿者/ 魔界の仮面弁士 (1940回)-(2010/11/16(Tue) 22:29:17)
No55098 (akira さん) に返信
> と@passwd、@uidの順に変数を設定するとプログラムが正しく動いてくれません。
System.Data.OleDb + Microsoft.JET.OLEDB.4.0 の組み合わせでは、
パラメータは「出現した順」で管理されます。パラメータの名前は無視されます。

ADO や DAO であれば、名前付きパラメータのまま扱えるのですけれどね。
引用返信 編集キー/
■55100 / inTopicNo.3)  Re[2]: OleDBでSQLに変数を渡す方法
□投稿者/ akira (15回)-(2010/11/16(Tue) 23:10:42)
No55099 (魔界の仮面弁士 さん) に返信
> ■No55098 (akira さん) に返信
>>と@passwd、@uidの順に変数を設定するとプログラムが正しく動いてくれません。
> System.Data.OleDb + Microsoft.JET.OLEDB.4.0 の組み合わせでは、
> パラメータは「出現した順」で管理されます。パラメータの名前は無視されます。
>
> ADO や DAO であれば、名前付きパラメータのまま扱えるのですけれどね。

魔界の仮面弁士さん、早急なアドバイスありがとうございます。
OleDb + MS-Access2003の組み合わせでは、 パラメータは「出現した順」で管理される。
パラメータの名前は無視されるのですか。残念です。

パラメータの名前は無視されてしまうのなら、OleDbを使用する際、なぜ
パラメータを「名前」「データ型」「サイズ」と非常に丁寧に設定してやらなけれ
ばならないのでしょうか?
objCom.Parameters.Add("@uid", OleDbType.VarWChar, 50)
objCom.Parameters("@uid").Value = txtUsr.Text
objCom.Parameters.Add("@passwd", OleDbType.VarWChar, 50)
objCom.Parameters("@passwd").Value = txtPass.Text

名前付きパラメータのまま扱えるSqlDB + SQL Serverの方は
objCom.Parameters.Add("@uid", txtUsr.Text)
objCom.Parameters.Add("@passwd", txtPass.Text)
ととてもシンプルに記述出来るのに? 疑問です?

OleDbでも、何か工夫すると、名前付きパラメータのまま扱える方法があるのでは?と
勘ぐってしまいます。
引用返信 編集キー/
■55101 / inTopicNo.4)  Re[2]: OleDBでSQLに変数を渡す方法
□投稿者/ 魔界の仮面弁士 (1941回)-(2010/11/16(Tue) 23:26:27)
No55099 (魔界の仮面弁士 さん) に返信
> System.Data.OleDb + Microsoft.JET.OLEDB.4.0 の組み合わせでは、
> パラメータは「出現した順」で管理されます。パラメータの名前は無視されます。
名前付きパラメータだとかえって誤解を与えるので、ばっさり諦めて、
 SELECT * FROM usr WHERE uid=? AND passwd=?
の位置パラメータ構文を使うようにしてみては如何でしょう。

可読性は低下しますが、登録順が重要な意味を持つという点を浮き彫りにできます。
後ろ向きな対応ですが…。



> ADO や DAO であれば、名前付きパラメータのまま扱えるのですけれどね。

一応 ADO 版を書いておきます。あまりおすすめはしませんが。

'ADODB.DLL を参照設定しておく必要があります。
'http://support.microsoft.com/kb/318559/ja

'接続文字列や値の確認のためのコードは省略しています。

Dim objCmd As ADODB.Command = New ADODB.CommandClass()
objCmd.ActiveConnection = objConn

'型情報をきちんと指定したい場合は、SQL に PARAMETERS ステートメントを入れておきます。
'これには、パラメータの出現順を意図的にする役目もあります。
objCmd.CommandText = "PARAMETERS userID TEXT(50), pwd TEXT(50); SELECT * FROM usr WHERE uid=userID AND passwd=pwd"

'Parameters.Refresh で、必要な型情報を取得できます。
'(ただし処理時間的には、自分で Parameters.Add した方が僅かに高速です)
Dim objParams As ADODB.Parameters = objCmd.Parameters
objParams.Refresh() 'ADO.NET でいうところの OleDbCommandBuilder.DeriveParameters に相当します。

'Refresh で名前が確定しているので、順番は無関係になります。
'もちろん、objParams(0) などでの指定もできますが。
Dim pwd As ADODB.Parameter = objParams("pwd") '「objParams!pwd」でも可。
Dim uid As ADODB.Parameter = objParams("userID") '「objParams!userID」でも可。

uid.Value = txtPass.Text
pwd.Value = txtPass.Text

'これらは COM オブジェクトのため、Marshal.ReleaseComObject の呼び出しが必要です。
'http://support.microsoft.com/kb/321415/ja
引用返信 編集キー/
■55102 / inTopicNo.5)  Re[2]: OleDBでSQLに変数を渡す方法
□投稿者/ akira (16回)-(2010/11/16(Tue) 23:27:38)
No55099 (魔界の仮面弁士 さん) に返信
> ■No55098 (akira さん) に返信
>>と@passwd、@uidの順に変数を設定するとプログラムが正しく動いてくれません。
> System.Data.OleDb + Microsoft.JET.OLEDB.4.0 の組み合わせでは、
> パラメータは「出現した順」で管理されます。パラメータの名前は無視されます。

OleDb + MS-Access2003の組み合わせでは、パラメータは「出現した順」で管理されるのなら

Dim objCom As New OleDbCommand("SELECT * FROM usr WHERE uid=? AND passwd=?", objDb)
objCom.Parameters.Add(New OleDbParameter("@temp", txtUsr.Text))
objCom.Parameters.Add(New OleDbParameter("@temp", txtPass.Text))

のコードでも正しく動くだろう。と書いて稼働を確認してみました。
このコードでも目的通り正しく動く事が確認できました。

でも、これではコードにドキュメント性がないので、無意味でも

Dim objCom As New OleDbCommand("SELECT * FROM usr WHERE uid=@uid AND passwd=@passwd", objDb)
objCom.Parameters.Add(New OleDbParameter("@uid", txtUsr.Text))
objCom.Parameters.Add(New OleDbParameter("@passwd", txtPass.Text))

と書いておいた方が良いですよね。
引用返信 編集キー/
■55103 / inTopicNo.6)  Re[3]: OleDBでSQLに変数を渡す方法
□投稿者/ 魔界の仮面弁士 (1942回)-(2010/11/16(Tue) 23:33:53)
No55100 (akira さん) に返信
> パラメータの名前は無視されてしまうのなら、OleDbを使用する際、なぜ
> パラメータを「名前」「データ型」「サイズ」と非常に丁寧に設定してやらなけれ
> ばならないのでしょうか?

OLE DB API の制限を受けているといえばそれまでですが、理由の一つとしては、
OLE DB が汎用的なミドルウェアである点が挙げられます。ODBC もそうですが。

System.Data.SqlClient は、SQL Server 専用ですが、
System.Data.OleDb は、扱える DB は OLE DB 次第です。

対象プロバイダーによっては、名前付きパラメータを持たないケースもありますし、
指定可能な型も、それぞれの OLE DB プロバイダーに依存しますし、
型情報を類推できるかどうかも、それぞれのプロバイダーによって異なります。

なので、専用ミドルウェアに比べると、多少の冗長さが生じてしまうのでしょう。


> OleDbでも、何か工夫すると、名前付きパラメータのまま扱える方法があるのでは?と
> 勘ぐってしまいます。
先ほど書いた例のように、ADO であれば扱えるので、ADO.NET でも何とかして欲しかったですね。。。

ADO.NET には OleDbCommandBuilder.DeriveParameters がありますが、ストアドにしか使えませんし。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -