ADO.NET OleDbTransaction

VB Tips And Sample(HOME)(VB.NET Sample インデックス)





データリーダ+コマンド、データアダプタ+データセット、データアダプタ+データセット+コマンドビルダの比較。
そいれぞれ一長一短あるのでうまく使い分けておく方がいいみたい。これ以外の組み合わせもいろいろありそう。
Private Sub DatarederADO()
        'データリーダで取得 コマンドで更新。 高速 だが SQL文などは全て自分で書く必要がある。 複数テーブルの更新などに便利。
        'データリーダは接続型なので 多くのレコードを取得する場合は不向き。データセットを使用したほうが良い。
一行ずつ取得する性質上、無線、バーチャルLANなどでは不向きか?

        Dim cn As New OleDbConnection
        Dim cmd As New OleDbCommand
        Dim dr As OleDbDataReader '読み取り専用前方スクロール
        Dim myTran As OleDbTransaction

        Dim i As Int32
        i = System.Environment.TickCount 'システム起動後のミリ秒単位の経過時間を取得します。

        Try

            cmd.Connection = cn
            cmd.CommandText = "SELECT * FROM Customers WHERE CustID=1"
            cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & Application.StartupPath & "\Order.mdb"
’VISTA上ではAccess2000形式はサポートされているらしい。Access2007でサポートされている為らしい。
            cn.Open()

’こいつで読み込む
            dr = cmd.ExecuteReader()
’こいつで読み込む
            If dr.Read = True Then
                'レコードが存在すれば
                dr.Close() 'データリーダを閉じてから行わないと fetching中と言う事でエラー

                myTran = cn.BeginTransaction(IsolationLevel.ReadCommitted)
                cmd.Transaction = myTran
                cmd.CommandText = "UPDATE Customers SET CustName='000' WHERE CustID=1"
                cmd.ExecuteNonQuery()

                '他にも同じ接続先への更新などが有ればSQL文を追加していく事ができる
                cmd.CommandText = "UPDATE Goods SET GoodsName='9999' WHERE GoodsID='A0001'"
                cmd.ExecuteNonQuery()

                myTran.Commit()'確定する

            End If


        Catch ex As Exception
            If myTran Is Nothing Then
            Else
                myTran.Rollback()
            End If
            MessageBox.Show(ex.ToString)
            Debug.WriteLine(ex.ToString)

        Finally
            dr.Close()
            cmd.Dispose()
            cn.Close()
            cn.Dispose()

        End Try
        i = System.Environment.TickCount - i
        Debug.WriteLine(i & "経過しました。")



    End Sub


    Private Sub DatasetADO()
        'データセットで取得 データアダプタのコマンドで更新。中速 データセットという非接続のテーブルをメモリ上に取得するので
        '多くのレコードなどを調べてどうするか決める場合に向いている。
クライアントPCメモリ上にデータセットというテーブルの集合を取得できるので、無線、VLANに向いている。
        'SQL文は自分で書く必要がある。


        Dim cn As New OleDbConnection
        Dim da As OleDbDataAdapter
        Dim ds As New DataSet
        Dim myTran As OleDbTransaction
        Dim i As Int32

        Dim X As Int32
        X = System.Environment.TickCount 'システム起動後のミリ秒単位の経過時間を取得します。


        Try

            cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & Application.StartupPath & "\Order.mdb"
            'cn.Open'データセット取得には必要なし
            da = New OleDbDataAdapter("SELECT * FROM Customers WHERE CustID=1", cn)

            da.Fill(ds, "Customers") '目的のデータを取得してデータセットに格納後自動的に接続は解除される
            If ds.Tables(0).Rows.Count >= 1 Then

                cn.Open() 'ExecuteNonQueryには接続OPENが必要
                'ゴリゴリ書いてUPDATE
                da.UpdateCommand = New OleDbCommand
                da.UpdateCommand.Connection = cn
                myTran = cn.BeginTransaction(IsolationLevel.ReadCommitted) 'トランザクションの開始
                'AccessではReadCommittedしかない?ReadUncommitted()でもエラー無しで通っているが?実際はReadCommittedしか使用しない。
                'Debug.WriteLine(myTran.IsolationLevel.ToString) 'ReadCommitted
                da.UpdateCommand.Transaction = myTran 'トランザクション属性付加?
                da.UpdateCommand.CommandText = "UPDATE Customers SET CustName='000' WHERE CustID=1"
                i = da.UpdateCommand.ExecuteNonQuery()
                '他にも同じ接続先への更新などが有ればSQL文を追加していく事ができる
                da.UpdateCommand.CommandText = "UPDATE Goods SET GoodsName='9999' WHERE GoodsID='A0001'"
                i = da.UpdateCommand.ExecuteNonQuery() 'ここで更新してもデータグリッドには反映されない

                myTran.Commit() 'トランザクションコミット
                'データセットは更新されていない
                'Debug.WriteLine(ds.Tables(0).Rows(0)("CustName"))
                cn.Close()
            End If


        Catch ex As Exception
            If myTran Is Nothing Then

            Else
                myTran.Rollback()
            End If

        End Try


        ds.Dispose()
        da.Dispose()
        cn.Dispose()

        X = System.Environment.TickCount - X 'システム起動後のミリ秒単位の経過時間を取得します。
        Debug.WriteLine(X & "経過しました。")
    End Sub




    Private Sub DataSet_ComadBUilADO()
        'データアダプタ +  データセット + コマンドビルダ
        'SQL文を書かなくても自動で更新などができるコマンドビルだだが最も低速。
        '多くのフィールドを持つテーブルなどの更新に便利。ただしAccessJET4.0は99フィールドまで。ANDは50まで。それ以上になると「クエリが複雑すぎます。」のエラー
[Query is too complex]でぐぐると多くのHPがある。
        ''http://support.microsoft.com/?id=192716
http://www.dotnet247.com/247reference/msgs/43/216266.aspx
        'また、複数のテーブルの更新となると、それごとのデータセットを取得する必要がある?


        Dim cn As New OleDbConnection
        Dim da As OleDbDataAdapter
        Dim ds As New DataSet
        Dim cmdb As New OleDbCommandBuilder 'データベースに関連付けられた DataSet への変更を調整するための単一テーブル コマンドを自動的に生成します。このクラスは継承できません。
        Dim myTran As OleDbTransaction


        Dim i As Int32

        i = System.Environment.TickCount

        Try

            cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & Application.StartupPath & "\Order.mdb"
            'cn.Open'必要なし

            da = New OleDbDataAdapter("SELECT * FROM Customers WHERE CustID=1", cn)

            da.Fill(ds, "Customers") '目的のデータを取得してデータセットに格納後自動的に接続は解除される

            If ds.Tables("Customers").Rows.Count > 0 Then

                cn.Open() 'トランザクションの為オープンする
                'コマンドビルダでお手軽UPDATE
                ds.Tables("Customers").Rows(0)("CustName") = "111"
                cmdb.DataAdapter = da
                da.UpdateCommand = cmdb.GetUpdateCommand
                'Debug.WriteLine(da.UpdateCommand.CommandText)

                myTran = cn.BeginTransaction(IsolationLevel.ReadCommitted)
                da.UpdateCommand.Transaction = myTran

                da.Update(ds, "Customers") 

                '他のテーブルは手動でUPDATE
                da.UpdateCommand.CommandText = "UPDATE Goods SET GoodsName='9999' WHERE GoodsID='A0001'"
                da.UpdateCommand.ExecuteNonQuery()

                myTran.Commit()
                cn.Close()
            End If

        Catch ex As System.Data.OleDb.OleDbException
            If myTran Is Nothing Then
            Else
                myTran.Rollback()
            End If
            MessageBox.Show(ex.ToString)
            Debug.WriteLine(ex.TargetSite)
            Debug.WriteLine(ex.Message)
            Debug.WriteLine(ex.ErrorCode)
            Debug.WriteLine(ex.ToString)
        ''''Int32 Update(System.Data.DataRow[], System.Data.Common.DataTableMapping)
        '''クエリが複雑すぎます。
        '''-2147467259
        '''''System.Data.OleDb.OleDbException: クエリが複雑すぎます。
        ''http://support.microsoft.com/?id=192716
http://www.dotnet247.com/247reference/msgs/43/216266.aspx
        End Try

        cmdb.Dispose()
        ds.Dispose()
        da.Dispose()
        cn.Dispose()

        i = System.Environment.TickCount - i
        Debug.WriteLine(i & "経過しました。")



    End Sub



VB Tips And Sample(HOME)(VB.NET Sample インデックス)