データベース

3246エラー「Connection オブジェクトは、トランザクション中に明示的に閉じることができません。」の対処法【Access VBA】


Error
3246エラー「Connection オブジェクトは、トランザクション中に明示的に閉じることができません。」

はじめに

ADODB.Connection を使ったトランザクション処理で、エラー3246が発生する場合について解説します。

以下、自分が遭遇したケースです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

'データベースに接続
Dim cn As New ADODB.Connection
Set cn = New ADODB.Connection
cn.Open DBLink

'実行したいSQL
Dim strSQL As String
strSQL = "INSERT INTO 猫 (名前, 色) VALUES (たま, 白), (ポチ, 三毛);"

'トランザクションの開始
cn.BeginTrans 
cn.Execute strSQL 'INSERT文の実行
cn.CommitTrans

cn.Close

問題

上記のように、テーブルに値を挿入するSQLを実行したい場合に、トランザクションエラーになりました。

3246番のエラーで検索すると、CloseやRollbackの問題ではないかという回答が得られますが、上記のようにトランザクションに不備はありません。

原因

SQL文に問題がありました。INSERT しようとしている値がすでに存在していたのが原因でした。

上の例では、猫テーブルに「たま」または「ポチ」の値がすでに存在していました。

解決方法

  • SQL文の要件を見直し、重複値が存在しないかを確認する
  • INSERT前に重複値を検索する代替クエリを実行
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
' INSERT前に重複値を検索
Dim rs As ADODB.Recordset
Set rs = cn.Execute("SELECT 名前 FROM 猫 WHERE 名前 IN ('たま', 'ポチ')")

If rs.EOF Then
    cn.Execute strSQL
    cn.CommitTrans
Else
    MsgBox "重複する値が存在します"
    cn.RollbackTrans
End If

まとめ

3246エラーの原因は、トランザクションの不備だけではなく、SQL文の不備にもありました。重複値を否定するロジックを入れることで問題を解決できる場合もあります。

まとめ
SQL文を見直すことで修正できるかもしれません