- ベストアンサー
VB6+SQL サーバー 2000 で 実行時エラー '3704' がでます:
VB6 + SQL サーバー 2000 でDB接続を行っていますが リストのように SELECT 文の後にInsert 文を実行しようとし Re.Closeを実行すると ------------------------------------------------------------- 実行時エラー '3704': オブジェクトが閉じている場合は、操作は許可されません ------------------------------------------------------------- とエラーになり、連続するSQL文を実行する場合のopen ,Close は どのように書けばよろしいのでしょうか。 ネット上で見つけた資料によるとメソッド RE.CancelUpdate を使うと ありましたがこれもエラーとなります。 どなたか 教えていただけないでしょうか。 --- sample ---------------------------------------- Dim Cn As New ADODB.Connection Dim Re As New ADODB.Recordset Connect = "" Connect = "Provider = SQLOLEDB;" _ & "Data Source = サーバー;" _ & "User ID = sa;" _ & "Password = パスワード;" _ & "initial Catalog = database;" ' Cn.Open Connect ' strSQL = "SELECT * from DBTBL WHERE CODE = '000001'" Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行 Re.Close ' strSQL = "Insert Into MAS1PF (CODE,NAME,TEL,FAX) Values('11111','名前','TEL,'FAX)" Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行 ' Re.Close Cn.Close
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
1:strSQL = "SELECT * from DBTBL WHERE CODE = '000001'" 2:Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行 3:Re.Close 4:strSQL = "Insert Into MAS1PF (CODE,NAME,TEL,FAX) Values('11111','名前','TEL,'FAX)" 5:Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行 の 3: で Re.Close したまま、5: で Re.Open しているからだと思います。 5: の前に Set Re = New ADODB.Recordset を入れると正常に動作するようになると思います。 ちなみに、なぜ 2: ではエラーが発生しないかというと、 Dim Re As ADODB.Recordset ではなく、 Dim Re As New ADODB.Recordset として宣言しているからです。
その他の回答 (1)
Private Sub Command1_Click() Dim strSQL(1) As String strSQL(0) = "INSERT INTO Table1 (ID, 顧客名) VALUES (3, 'AAA')" strSQL(1) = "INSERT INTO Table1 (ID, 顧客名) VALUES (4, 'BBB')" CnnExecute strSQL(0) CnnExecute strSQL(1) End Sub No1さんの回答で不具合自体は解消されています。 が、幾つか改善すべき点もあるようです。 CnnExecute関数は、conCNNSTRING を SQL Server 2000 のそれに変更しての動作確認も済んでいます。 改善点1、ADODB のエラー管理を行う。 改善点2、トランザクションのロールバックも行う。 なお、Set cnn = New ADODB.Connection を複数回実行するのであれば関数にすればよい。 そうすれば、 Command1_Click() のように非手続き的に安直の書くことも可能。 Const conCNNSTRING = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\temp\db1.mdb" Public Function CnnExecute(ByVal strSQL As String) As Boolean On Error GoTo Err_CnnExecute Dim isOK As Boolean Dim cnn As ADODB.Connection isOK = True Set cnn = New ADODB.Connection With cnn .Errors.Clear .ConnectionString = conCNNSTRING .Open .BeginTrans .Execute strSQL .CommitTrans End With Exit_CnnExecute: On Error Resume Next CnnExecute = isOK Exit Function Err_CnnExecute: isOK = False If cnn.Errors.Count > 0 Then ErrMessage cnn.Errors(0), strSQL cnn.RollbackTrans Else MsgBox "プログラムエラーが発生しました。システム管理者に報告して下さい。(CnnExecute)", _ vbExclamation, " 関数エラーメッセージ" End If Resume Exit_CnnExecute End Function Public Sub ErrMessage(ByVal CnnErrors As ADODB.Error, ByVal strSQL As String) MsgBox "ADOエラーが発生しましたので処理をキャンセルします。" & Chr$(13) & Chr$(13) & _ "・Err.Description=" & CnnErrors.Description & Chr$(13) & _ "・Err.Number=" & CnnErrors.Number & Chr$(13) & _ "・SQL State=" & CnnErrors.SQLState & Chr$(13) & _ "・SQL Text=" & strSQL, _ vbExclamation, " ADO関数エラーメッセージ" End Sub
お礼
良きアドバイス ありがとうございます。 たいへん 勉強になります。 早速ためしてみます。
お礼
insert,update,delete の場合は Execute を使いなさいと文書を 見つけました。 Executeだと re.close は不要との記述もありました。 試したところイメージ通りの処理ができていますので、これでやってみようと 思います。 本当にありがとうございました。
補足
tukasa-12r さんありがとうございます。早速 試してみたのですが同じエラーが発生します。 Dim Cn1 As New ADODB.Connection Dim Re As ADODB.Recordset vProv = "Provider = SQLOLEDB;" _ & "Data Source = サーバー;" _ & "User ID = sa;" _ & "Password = パスワード;" _ & "initial Catalog = database;" Cn1.Open vProv 'Db OPEN strSQL = "SELECT * from DBTBL WHERE CODE = '000001'" Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行 Re.Close strSQL = "Insert Into MAS1PF (CODE,NAME,TEL,FAX) Values('11111','名前','TEL,'FAX)" Set Re = New ADODB.Recordset Re.Open strSQL, Cn, adOpenKeyset 'SQL文を実行 Re.Close ← ここでエラー 3704 がでます もう少し教えていただけないでしょうか。