none
クラスに記載したデータベースの戻り値が取得できるものとできないものがあります。これは正しいのでしょうか? RRS feed

  • 質問

  • 初歩的なことですみません。

    データベースアクセスのロジックをクラス化しようと思うのですが、下記のようにDatatableは戻せるのにDatareaderはエラーに

    なります。もともと戻り値にできないのか、クラスの書き方が悪いのかがわからないので、ご存じの方ご教授いただけないでしょうか?

    よろよろしくお願いいたします。

    sub DetaGet()

        sbSql.Clear()
        sbSql.Append("select  *")
        sbSql.Append("  from  master")
        sbSql.Append(" where  key  =  '001'")
        データテーブルにはデータが戻される 

        Dim sqlDataTable As DataTable = clsDbtask.GetDataTable(sbSql, mstrDBString)

        こちらはエラーになる
        Dim SqlDataReader As SqlDataReader = clsDbtask.GetDataReader(sbSql, mstrDBString)

    End Sub
        Public Function GetDataTable(ByVal StrSql As StringBuilder, ByVal cns As String) As DataTable
            Dim SqlDataTable As New DataTable
            Try
                Using AdoCn As New SqlConnection
                    AdoCn.ConnectionString = cns
                    AdoCn.Open()
                    Using adoCm As New SqlCommand
                        adoCm.CommandType = CommandType.Text
                        adoCm.Connection = AdoCn
                        adoCm.CommandText = StrSql.ToString
                        Using AdoDa As New SqlDataAdapter
                            AdoDa.SelectCommand = adoCm
                            AdoDa.Fill(SqlDataTable)
                        End Using
                    End Using
                End Using
            Catch ex As Exception
                Throw ex
            End Try
            Return SqlDataTable
        End Function
        Public Function GetDataReader(ByVal sbSql As StringBuilder, ByVal cns As String) As SqlDataReader
            Dim SqlDataReader As SqlDataReader
            Try
                Using adoCn As New SqlConnection
                    adoCn.ConnectionString = cns
                    adoCn.Open()
                    Using adoCm As New SqlCommand
                        adoCm.Connection = adoCn
                        adoCm.CommandType = CommandType.Text
                        adoCm.CommandText = sbSql.ToString
                        SqlDataReader = adoCm.ExecuteReader
                    End Using
                End Using
            Catch ex As Exception
                Throw ex
            End Try
            Return SqlDataReader
            SqlDataReader.Close()
        End Function


    2019年6月28日 3:32

回答

  • 「エラーになる」だけじゃ、コンパイルエラーなのか実行時例外なのかすら分かりません。どういう「エラー」とやらが出ているのか書いてください。

    とりあえず、パッと見た限り、SqlConnectionやSqlCommand, SqlDataReaderを「GetDataReaderの中で」UsingやCloseしてるのはまずいです。SqlDataReaderがデータを読み取り切るまで、これらを破棄してはいけません。

    SqlDataReaderがデータを読み取るのはメソッドから返った後になるので、そうなると、このGetDataReaderの形式だとSqlConnectionをCloseする手段がなくなることになり、この形式はそもそもよろしくないということになります。

    ちなみにGetDataTableの方は、メソッド内で全部データを読み取ることになるので、SqlConnectionをメソッド内でCloseできます。


    • 編集済み Hongliang 2019年6月28日 3:44
    • 回答としてマーク qoo_man 2019年6月28日 10:29
    2019年6月28日 3:43

すべての返信

  • 「エラーになる」だけじゃ、コンパイルエラーなのか実行時例外なのかすら分かりません。どういう「エラー」とやらが出ているのか書いてください。

    とりあえず、パッと見た限り、SqlConnectionやSqlCommand, SqlDataReaderを「GetDataReaderの中で」UsingやCloseしてるのはまずいです。SqlDataReaderがデータを読み取り切るまで、これらを破棄してはいけません。

    SqlDataReaderがデータを読み取るのはメソッドから返った後になるので、そうなると、このGetDataReaderの形式だとSqlConnectionをCloseする手段がなくなることになり、この形式はそもそもよろしくないということになります。

    ちなみにGetDataTableの方は、メソッド内で全部データを読み取ることになるので、SqlConnectionをメソッド内でCloseできます。


    • 編集済み Hongliang 2019年6月28日 3:44
    • 回答としてマーク qoo_man 2019年6月28日 10:29
    2019年6月28日 3:43
  • HongLiang様

    >とりあえず、パッと見た限り、SqlConnectionやSqlCommand, SqlDataReaderを「GetDataReaderの中で」UsingやCloseしてるのはまずいです。SqlDataReaderがデータを読み取り切るまで、これらを破棄してはいけません。

    そうだと思っていませんでした。

    SqlDataReaderで別の変数にデータをセットして結果を返すことにしました。

    レコードでデータを引用するときはDetaTableを使うようにします。

    ありがとうございました。

    2019年6月28日 10:28