- PR -

ExecuteNonQueryの例外処理

1
投稿者投稿内容
damepg
大ベテラン
会議室デビュー日: 2003/03/19
投稿数: 229
お住まい・勤務地: 東京都内
投稿日時: 2003-05-07 12:17
下記の様なSQLをExecuteNonQueryで実行し、そのクイックウォッチをみると
下記のエラーが出ているのですが、Catchできません。どうしてでしょうか?
しかし、DBには登録できています。

「実行時例外がスローされました : System.Data.SqlClient.SqlException - PRIMARY KEY 違反、制約 'T_adm_DailyReport_Info_PK': オブジェクト 'T_adm_DailyReport_Info' には重複したキーは挿入できません。ステートメントは終了されました。」

strSQL = ""
strSQL = strSQL & "INSERT INTO T_adm_DailyReport_Info VALUES( "
strSQL = strSQL & "@SiteID, @Sales_Year, @Sales_Month, @Sales_Date, "
strSQL = strSQL & "@Input_Person, @FRameA, @FrameB, @Weather, @LastUpdate )"
Cmd.CommandText = strSQL

'パラメータ設定
Cmd.Parameters.Add("@SiteID", SqlDbType.Char, 3)
Cmd.Parameters("@SiteID").Value = DailyRep.SiteID
Cmd.Parameters.Add("@Sales_Year", SqlDbType.Char, 4)
Cmd.Parameters("@Sales_Year").Value = DailyRep.Sales_Year
Cmd.Parameters.Add("@Sales_Month", SqlDbType.Char, 2)
Cmd.Parameters("@Sales_Month").Value = DailyRep.Sales_Month
Cmd.Parameters.Add("@Sales_Date", SqlDbType.Char, 2)
Cmd.Parameters("@Sales_Date").Value = DailyRep.Sales_Date
Cmd.Parameters.Add("@Input_Person", SqlDbType.VarChar, 50)
Cmd.Parameters("@Input_Person").Value = DailyRep.Input_Person
Cmd.Parameters.Add("@FRameA", SqlDbType.Int)
Cmd.Parameters("@FRameA").Value = DailyRep.FrameA
Cmd.Parameters.Add("@FrameB", SqlDbType.Int)
Cmd.Parameters("@FrameB").Value = DailyRep.FrameB
Cmd.Parameters.Add("@Weather", SqlDbType.VarChar, 50)
Cmd.Parameters("@Weather").Value = DailyRep.Weather
Cmd.Parameters.Add("@LastUpdate", SqlDbType.DateTime)
Cmd.Parameters("@LastUpdate").Value = sDate

Cmd.ExecuteNonQuery()


[ メッセージ編集済み 編集者: damepg 編集日時 2003-05-07 12:28 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-05-07 14:53
こんにちは。

引用:

damepgさんの書き込み (2003-05-07 12:17) より:

下記の様なSQLをExecuteNonQueryで実行し、そのクイックウォッチをみると
下記のエラーが出ているのですが、Catchできません。どうしてでしょうか?
しかし、DBには登録できています。

「実行時例外がスローされました : System.Data.SqlClient.SqlException - PRIMARY KEY 違反、制約 'T_adm_DailyReport_Info_PK': オブジェクト 'T_adm_DailyReport_Info' には重複したキーは挿入できません。ステートメントは終了されました。」



 SQL Serverが出している「PRIMARY KEY 違反」の意味は理解されているでしょうか。この制約違反は、「同じ値を2つ以上登録することはできない」というプライマリキー制約に違反しているために発生しています。この制約に違反するデータは登録されません。「DBには登録できています」とおっしゃいますが、どのようにして確認されましたか?検索して見つかっただけでは「登録できている」とは言えません。登録しようとした数と、登録されている数が同じか、検証してみてください。

 具体的には、テーブルを次の様に定義し、

CREATE TABLE TEST_TABLE (
P_KEY AS DECIMAL PRIMARY KEY,
SETTING_VALUE AS CHAR(64)
)

テーブルに何のデータも入っていないと仮定して、次の様なINSERT文を発行すると、3つ目のINSERT文で発生します。

INSERT INTO TEST_TABLE (P_KEY, SETTING_VALUE) VALUES (1, 'FIRST DATA')
INSERT INTO TEST_TABLE (P_KEY, SETTING_VALUE) VALUES (2, 'NOT ERROR')
INSERT INTO TEST_TABLE (P_KEY, SETTING_VALUE) VALUES (1, 'THIS IS ERROR')

ここで、1つ目のINSERT文は制約違反になりません。テーブルにデータがないのでP_KEY列に対するデータ'1'は、テーブル中に1つしか存在しないからです。同様に2つ目も、データ'2'がテーブル中に存在しないので制約違反にはなりません。しかし、3つ目でデータ'1'をもう1つ挿入しようとしています。このとき、プライマリキー制約違反が発生します。しかし、1つ目のINSERT文は成功しているので、「SELECT * FROM TEST_DATA WHERE P_KEY = 1」とすると、データが1行返ってきます。


 catch については、どのクラスをどのようにキャッチしようとしているかがわからないので何とも言えません。
damepg
大ベテラン
会議室デビュー日: 2003/03/19
投稿数: 229
お住まい・勤務地: 東京都内
投稿日時: 2003-05-07 15:12
引用:

 SQL Serverが出している「PRIMARY KEY 違反」の意味は理解されているでしょうか。この制約違反は、「同じ値を2つ以上登録することはできない」というプライマリキー制約に違反しているために発生しています。この制約に違反するデータは登録されません。「DBには登録できています」とおっしゃいますが、どのようにして確認されましたか?検索して見つかっただけでは「登録できている」とは言えません。登録しようとした数と、登録されている数が同じか、検証してみてください。



登録しようとしたデータはDBには存在しません。
なので、PRIMARY KEY 違反はないと思うのですが、ExecuteNonQueryで制約違反が
発生しています。しかし、登録しようとしたデータは登録できています。
Crime
常連さん
会議室デビュー日: 2002/08/26
投稿数: 34
お住まい・勤務地: Japan
投稿日時: 2003-05-07 15:43
もしかしたらExecuteNonQueryが2回動いてるってことはないですかね?
前後のコードがわかりませんので、もしかしたら。っていう推測ですが。
damepg
大ベテラン
会議室デビュー日: 2003/03/19
投稿数: 229
お住まい・勤務地: 東京都内
投稿日時: 2003-05-07 16:13
dim a as integer = CmdDaily.ExecuteNonQuery
としてみましたが、a=1となり正常にINSERTできているように思えます。
なぜが、クウィックウォッチでみると、「制約違反の例外がスロー」が
表示されています。しかし、この例外をCatch出来ません。

引用:

登録しようとしたデータはDBには存在しません。
なので、PRIMARY KEY 違反はないと思うのですが、ExecuteNonQueryで制約違反が
発生しています。しかし、登録しようとしたデータは登録できています。

いのつち
ベテラン
会議室デビュー日: 2002/05/14
投稿数: 73
投稿日時: 2003-05-07 17:10
引用:

なぜが、クウィックウォッチでみると、「制約違反の例外がスロー」が
表示されています。しかし、この例外をCatch出来ません。



クイックウォッチで、 CmdDaily.ExecuteNonQuery を 選択して、ウオッチしている
のではないでしょうか?

クィックウォッチで状態を見たときにその処理を1度実行したことになります。
だから、CmdDaily.ExecuteNonQuery 実行後にウォッチすれば、
2度目の処理で重複の例外が出ますよね。
逆に、デバッグで、CmdDaily.ExecuteNonQueryの直前にウォッチすると、
ウォッチの結果は1が返って、その後デバッグ実行を進めると、実際のコードで
例外にひっかかることになると思います。

damepg
大ベテラン
会議室デビュー日: 2003/03/19
投稿数: 229
お住まい・勤務地: 東京都内
投稿日時: 2003-05-07 17:26
まさにおっしゃる通りです。
選択してウォッチすると一度実行されたことになるのですね。

一度、CmdDaily.ExecuteNonQueryを実行した後に、この部分を選択して
ウォッチしたので、制約違反の例外がウォッチに出ていたのです。
逆にCmdDaily.ExecuteNonQueryを実行する前に、この部分を選択したら
1とウォッチに表示されました。そして、プログラムからCmdDaily.ExecuteNonQueryを
実行したら、例外もcatchできました。

ありがとうございました。助かりました。

引用:

いのつちさんの書き込み (2003-05-07 17:10) より:

クイックウォッチで、 CmdDaily.ExecuteNonQuery を 選択して、ウオッチしている
のではないでしょうか?

クィックウォッチで状態を見たときにその処理を1度実行したことになります。
だから、CmdDaily.ExecuteNonQuery 実行後にウォッチすれば、
2度目の処理で重複の例外が出ますよね。
逆に、デバッグで、CmdDaily.ExecuteNonQueryの直前にウォッチすると、
ウォッチの結果は1が返って、その後デバッグ実行を進めると、実際のコードで
例外にひっかかることになると思います。

1

スキルアップ/キャリアアップ(JOB@IT)