アプリ版:「スタンプのみでお礼する」機能のリリースについて

VB.net のモジュールの引数にについての質問です。
やりたい事はSQLServerへの接続およびSELCT文を実行させることです
DB側へのセッションをモジュールで作成し、
それを元に、他のモジュールやクラスファイルで
selectやinsertを動かしたいと思っていますが、うまくいきません

「ExecuteReader には接続が開かれていて使用可能なことが必要です。
現在の接続の状態は終了です」というエラーが出てしまいます。
おそらく戻り値のあたりがおかしいのかなと思うのですが、
解決策がわかりません。



Module Connect

Dim cn As System.Data.SqlClient.SqlConnection

Public Function Connection()
Try
cn = New System.Data.SqlClient.SqlConnection()

'SQL Server認証を利用して接続
cn.ConnectionString = _
"Data Source = " & ServerName & _
";Initial Catalog = " & DBName & _
";User ID = " & UserID & _
";Password = " & password

'Windows認証を利用して接続
'cn.ConnectionString = _
' "Data Source = " & ServerName & _
' ";Initial Catalog = " & DBName & _
' ";Integrated Security = SSPI"

cn.Open()

MessageBox.Show("接続されました")


Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try

Return cn
End Function

End Module



Public Sub ExecuteReaderTest()
Try
Dim cn As New System.Data.SqlClient.SqlConnection

Connection()

Dim hCommand As System.Data.SqlClient.SqlCommand = cn.CreateCommand()


hCommand.CommandText = "SELECT ~~ "


Dim cReader As System.Data.SqlClient.SqlDataReader = hCommand.ExecuteReader()

hCommand.Dispose()

......

A 回答 (3件)

あなたが作成したConnectionメソッドは最後にcnという変数の内容を


Returnしていますよね。
これは「System.Data.SqlClient.SqlConnection」型の戻り値を持つ、
つまり「Public Function Connection()」
でなく「Public Function Connection() As System.Data.SqlClient.SqlConnection」
ではないかと思ったのです。

とすれば狙いとしては、ConnectモジュールのConnectionメソッドで
作成した接続を例えばExecuteReaderTestメソッドなどで使いたいの
かと。

であれば、ExecuteReaderTestメソッドでは

Public Sub ExecuteReaderTest()
Try
Dim cn As New System.Data.SqlClient.SqlConnection
cn = Connect.Connection()

Dim hCommand As System.Data.SqlClient.SqlCommand
hCommand = cn.CreateCommand()

hCommand.CommandText = "SELECT ~~ "

Dim cReader As System.Data.SqlClient.SqlDataReader
cReader = hCommand.ExecuteReader()
Finally
hCommand.Dispose()
End Sub

という風にConnectionの戻り値を利用する形式に変更すべきかと。
(上記はあくまでも説明のためのサンプルです)

今後、Connectionで作ったものを使いまわすならredfox63様の
ご指摘も踏まえて少しつくりを変える必要があると思いますが、
戻り値の割り当てとはこんな感じのことをイメージしています。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
戻り値についてもう少し勉強します。

お礼日時:2009/04/21 21:11

おかしいと思われたポイントはあっていると思います。


・Connection()はFunctionなのに戻り値がありません。VisualStudioを
 何も考えずにインストールするとビルドエラーになるのでは?
(質問への転記ミス?)
・ExecuteReader()は内部でコンストラクタを使ってインスタンスを
 作成していますので、cnは閉じた接続です。
 従ってConnection()を呼び出してもどこにも何も反映されません。

つまり、
・Newする代わりにConnection()の戻り値を割り当てる
ようにすれば、うまくいくのではないかと。

この回答への補足

回答ありがとうございます
戻り値を用意するというのがよくわかりません。

Connection()の戻り値の割り当て方法とか
どのようにやればよいのでしょうか?

補足日時:2009/03/31 21:35
    • good
    • 0

> Public Sub ExecuteReaderTest()


> Try
 ' このcnを使いたいなら Connectionメソッドに引数でわたすなどの
 ' 措置が必要
 ' グローバルのcnを使用するなら コメントアウトしましょう
> Dim cn As New System.Data.SqlClient.SqlConnection
>
> Connection()

> Dim hCommand As System.Data.SqlClient.SqlCommand = cn.CreateCommand()

このExecuteReaderTestの中にローカルのcnを作ってしまうと
モジュールレベルの cnをその後の『Dim hCommand ...』の行などで使いません

ローカルとグローバル(モジュール/クラス)で同名の変数がある場合
より近くで解決できる変数を使うことになるので、ローカル変数が優先されます

したがって cnは newでインスタンス(実体)化はされているが
接続方法も設定されていないし、Openもされていない状態になります

この回答への補足

回答ありがとうございます
> Dim cn As New System.Data.SqlClient.SqlConnection
>
> Connection()
をコメントアウトして、cnをConnection変更してみました
Dim hCommand As System.Data.SqlClient.SqlCommand = Connection.CreateCommand()。
ロジック的にはこれでよいのでしょうか?

補足日時:2009/03/31 21:28
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A