QA@IT
この質問・回答は、@ITの旧掲示板からインポートされたものです。

DBからの値の取得

失礼します。
VB.NETで開発を始めたばかりの初心者で本を片手に開発しているのですが、エラーが出てどうしてもわかりません。どなたかご教授ください。

下のプログラムでOracleから日付を取得したいのですが、
オブジェクトの現在の状態に問題があるため、操作は有効ではありません。
というエラーがでます。エラーが出るところで一度止めてから走らせると正しく処理してくれるのですが・・・どうすればこのエラーを回避できますか?よろしくおねがいします。

Public Shared Function GetDBSysdate(ByRef connection As OracleConnection, ByRef strFormat As String) As String
Dim sysdateToday As Date
Dim command As OracleCommand = New OracleCommand("SELECT SYSDATE FROM DUAL", connection)
connection.Open()
Dim reader As OracleDataReader = command.ExecuteReader

sysdateToday = CType(reader("SYSDATE"), Date)  'エラー

reader.Close()      
connection.Close()  

If strFormat <> "" Then
    GetDBSysdate = Format(sysdateToday, strFormat)
Else
    GetDBSysdate = CType(sysdateToday, String)
End If

End Function

質問者:たつ

回答

私は以下のように、ExecuteScalar メソッドを使います。




    Public Shared Function GetServerDate() As System.DateTime
        Dim hConnection As System.Data.OracleClient.OracleConnection

        Try
            hConnection = New System.Data.OracleClient.OracleConnection("...")
            Dim hCommand As System.Data.OracleClient.OracleCommand

            Try
                hCommand = New System.Data.OracleClient.OracleCommand("SELECT SYSDATE FROM DUAL", hConnection)
                hConnection.Open()

                Try
                    Return DateTime.Parse(hCommand.ExecuteScalar().ToString())
                Catch exOracle As System.Data.OracleClient.OracleException
                    Throw exOracle
                Finally
                    If Not hConnection Is Nothing Then
                        hConnection.Close()
                    End If
                End Try
            Finally
                If Not hCommand Is Nothing Then
                    hCommand.Dispose()
                End If
            End Try
        Finally
            If Not hConnection Is Nothing Then
                hConnection.Dispose()
            End If
        End Try
    End Function

_________________C# と VB.NET の入門サイト
じゃんぬねっと日誌

投稿者:じゃんぬねっと

編集 履歴 (0)

ありがとうございます!
ExecuteScalar メソッドを使うとエラーが出なくなりました。

この場合ExecuteReaderは駄目だったのでしょうか?

投稿者:たつ

編集 履歴 (0)

Readしていない。

投稿者:todo

編集 履歴 (0)

たつさんの書き込み (2005-11-22 17:56) より:

この場合ExecuteReaderは駄目だったのでしょうか?

todo さんの仰る通り Read メソッドを事前に呼び出していないためです。
ExecuteReader バージョンを書きます。




    Public Shared Function GetServerDate() As System.DateTime
        Dim hConnection As System.Data.OracleClient.OracleConnection

        Try
            hConnection = New System.Data.OracleClient.OracleConnection("...")
            Dim hCommand As System.Data.OracleClient.OracleCommand

            Try
                hCommand = New System.Data.OracleClient.OracleCommand("SELECT SYSDATE FROM DUAL", hConnection)
                hConnection.Open()

                Try
                    Dim hReader As System.Data.OracleClient.OracleDataReader

                    Try
                        hReader = hCommand.ExecuteReader()

                        If hReader.Read() Then
                            Return DateTime.Parse(hReader("SYSDATE").ToString())
                        End If
                    Finally
                        If Not hReader Is Nothing Then
                            Try
                                hReader.Close()
                            Finally
                                hReader.Dispose()
                            End Try
                        End If        
                    End Try
                Finally
                    If Not hConnection Is Nothing Then
                        hConnection.Close()
                    End If
                End Try
            Finally
                If Not hCommand Is Nothing Then
                    hCommand.Dispose()
                End If
            End Try
        Finally
            If Not hConnection Is Nothing Then
                hConnection.Dispose()
            End If
        End Try
    End Function

今回は 1 データのみの取得ですので、ExecuteScalar メソッドの方が良いでしょう。

_________________C# と VB.NET の入門サイト
じゃんぬねっと日誌

投稿者:じゃんぬねっと

編集 履歴 (0)

コードはじゃんぬさんとかぶるので、書くときの注意。

 VB では関数名の変数を暗黙で用意してくれますが、他の言語の人にとってわかりにくいことこの上ありません。戻り値用の変数を用意しましょう。

 リファレンスを調べ、IDispose インターフェイスを実装しているか、確認します。実装しているクラスのインスタンスは、使い終わったら必ず Dispose します。このように、Try 〜 Finally で囲み、Finally ブロックで Dispose します。

 文字列への変換は、独自にフォーマット関数を作るのではなく、String.Format や ToString メソッドを利用します。

 データベースからいきなり get すると、null 値の場合に例外が生成されます。IsDBNull で検査して、場合分けをします。

 空文字列の検査は、Length で検査するか、String.Empty と比較します。"" だと、ここにオブジェクトが生成されます。


□ written by Jitta on 2005/11/22
□ Microsoft MVP for Visual Developer ASP/ASP.NET Oct.2005-Sept.2006


投稿者:Jitta

編集 履歴 (0)

todoさん、じゃんぬねっとさん、Jittaさんありがとうございます!
大変勉強になりました。
もっと勉強しますが、分からない所が出てきたらまたよろしくお願いします。

投稿者:たつ

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。