- - PR -
SQLparameterとトランザクション
1|2|3
次のページへ»
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2006-02-17 11:34
先日、「INSERTのVALUESの値に閉じていない括弧が存在する場合」
という件名で質問させていただき、その際にSQLparameterで実行する やり方を教えていただきました。 今までのプログラムを変更しているのですが、 トランザクション処理を使用しているプログラムがエラーになりました。 原因を色々調べたのですが、よく分からず困っております。 エラーを検索してもほとんど情報が出てきませんでした。 処理はこのように行っており 1.トランザクション開始 2.SQLパラメータを使用した追加クエリ 3.エラーがなければコミット 4.エラーがあればロールバック 3のコミット時にエラーが出ます。エラーの内容はこれです。 EXECUTE 後のトランザクション数は、 COMMIT TRAN または ROLLBACK TRAN ステートメントに間違いがあることを示しています。以前の数 = 1、現在の数 = 0 です。 SQLパラメータを使用しない場合は問題なく実行できます。 組合わせで使用ができないということはあるのでしょうか? 何か分かる方がいらっしゃいましたらアドバイスよろしくお願い致します。 | ||||
|
投稿日時: 2006-02-17 12:49
SqlParameterを使用しても問題なくトランザクション処理は行えます。
どのようなコードを書いたのか最低限のコードを書いてもらえると回答しやすいのですが。。。 | ||||
|
投稿日時: 2006-02-17 13:30
burton999さん、できるんですね。 ソースは要約したらこんな感じです。よろしくお願いします。 Public Class F_buhintori Dim CN As New SqlClient.SqlConnection Dim CMD As New SqlClient.SqlCommand Dim DR As SqlClient.SqlDataReader Dim ERRORECODE As Integer Dim ERROREMSG As String Private Sub btn_受注取込_Click CN.ConnectionString = "Server=" & DB_SERVER & ";Initial Catalog=" & DB_CATALOG & ";User ID=" & DB_USER & ";Password=" & DB_PASSWORD & ";" CN.Open() CMD.Connection = CN begintransaction() make_item() If ERRORECODE = 0 Then committransaction() Else rollbacktransaction() End If If ERRORECODE = 0 Then MsgBox("取込が終了しました") Else MsgBox(ERROREMSG) End If End Sub Function make_item() CMD.CommandText = ="INSERT INTO TEST_TABLE (a, b) VALUES 'ABCD',@Sqlp_b)" CMD.Parameters.Clear() CMD.Parameters.Add(New SqlClient.SqlParameter("@Sqlp_b", SqlDbType.VarChar,5)) CMD.Parameters("@Sqlp_b").Value = 'YUI(O' Try CMD.ExecuteNonQuery() Catch ex As Exception ERRORECODE = 3 ERROREMSG = ex.ToString End Try End Function Function begintransaction() CMD.CommandText = "BEGIN TRANSACTION" Try CMD.ExecuteNonQuery() Catch ex As Exception ERRORECODE = 1 ERROREMSG = ex.ToString End Try End Function Function rollbacktransaction() CMD.CommandText = "ROLLBACK TRANSACTION" Try CMD.ExecuteNonQuery() Catch ex As Exception ERRORECODE = 1 ERROREMSG = ex.ToString End Try End Function Function committransaction() CMD.CommandText = "COMMIT TRANSACTION" Try CMD.ExecuteNonQuery() Catch ex As Exception ERRORECODE = 1 ERROREMSG = ex.ToString End Try End Function End Class | ||||
|
投稿日時: 2006-02-17 13:38
トランザクション処理をSqlCommandでやっているのですね。。。
SqlClient.SqlConnectionクラスにBeginTransaction()メソッドがあり このメソッドがSqlTransactionを返すので、それを使用したほうがよろしいかと。 ちなみにSqlTransactionクラスはSqlComandクラスのTransactionプロパティに設定します。 SqlTransaction クラス http://www.microsoft.com/japan/msdn/library/ja/cpref/html/frlrfsystemdatasqlclientsqltransactionclasstopic.asp?frame=true | ||||
|
投稿日時: 2006-02-17 13:51
ほとんど我流なんで…;なんかおかしい方法みたいですね、恥ずかしい…。 SqlClient.SqlConnectionクラスのBeginTransaction()メソッド 調べてから試してみようと思います。 burton999さん、ありがとうございました。 | ||||
|
投稿日時: 2006-02-17 14:54
SQLparameterとトランザクションでエラーなく
実行できるようになりました。 burton999さん、ありがとうございました。 Imports System.Data.SqlClient Public Class F_buhintori Dim CN As New SqlClient.SqlConnection Dim CMD As New SqlClient.SqlCommand Dim TRANS As SqlTransaction Dim ERRORECODE As Integer Dim ERROREMSG As String Private Sub btn_受注取込_Click CN.ConnectionString = "Server=" & DB_SERVER & ";Initial Catalog=" & DB_CATALOG & ";User ID=" & DB_USER & ";Password=" & DB_PASSWORD & ";" CN.Open() TRANS = CN.BeginTransaction() CMD.Connection = CN CMD.Transaction = TRANS make_item() If ERRORECODE = 0 Then Try TRANS.Commit() Catch ex As SqlException Try TRANS.Rollback() ERRORECODE = 1 ERROREMSG = ex.ToString Catch ex2 As SqlException ERRORECODE = 1 ERROREMSG = ex2.ToString End Try End Try Else Try TRANS.Rollback() Catch ex As SqlException ERRORECODE = 1 ERROREMSG = ex.ToString End Try End If If ERRORECODE = 0 Then MsgBox("取込が終了しました") Else MsgBox(ERROREMSG) End If End Sub Function make_item() CMD.CommandText = ="INSERT INTO TEST_TABLE (a, b) VALUES 'ABCD',@Sqlp_b)" CMD.Parameters.Clear() CMD.Parameters.Add(New SqlClient.SqlParameter("@Sqlp_b", SqlDbType.VarChar,5)) CMD.Parameters("@Sqlp_b").Value = 'YUI(O' Try CMD.ExecuteNonQuery() Catch ex As Exception ERRORECODE = 3 ERROREMSG = ex.ToString End Try End Function End Class | ||||
|
投稿日時: 2006-02-17 22:20
ん〜。。。まぁ、「動けばいい」なら、いいんですけど、今日、こんなソースをメンテして泣いたので。
* SqlClient.SqlConnection など、IDispose インターフェイスを実装したものは、必ず Dispose(または Close)してください。 * その為、クラス変数として宣言するのではなく、メソッド内に宣言して、スコープを限定してください。 * 例外は、必要なければキャッチしないでください。キーパー以外はハンドで反則ですよ。 * 実際には複数の処理があるんだろうけど、もし、1ステートしか実行させないなら、トランザクションを貼る必要はないですよ。 * Function は、必ず戻り型を宣言してください。
| ||||
|
投稿日時: 2006-02-18 02:11
いつも書いていることを先に書かれた...
私の場合はそれプラス、使う直前に変数を宣言して 必ず、Try 〜 Finally パターンを使ってもっとスコープを限定します。 Command、Transaction も一応 IDispose インターフェイスを実装しているので、 どうしても、Dispose しておかないとしっくりこない。 たいてい、Jitta さんの言うように「メソッド内」のみに記述することが多く、 数コマンド連続で実行することも少ないので、ラッパークラスを組むこともあります。 主にインデントの節約と、新人らの工数短縮などがその要因だったりしますが。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 |
1|2|3
次のページへ»