質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

2回答

16862閲覧

例外処理(Tryの内容)

yyy

総合スコア49

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

1クリップ

投稿2016/08/09 02:53

編集2016/08/12 00:29

###前提・実現したいこと
SQL更新実行の処理を行う際にエラーが発生した場合(SQLが成立しない場合?)に例外処理が行われるようにコードを書きたい。
しかし、Tryブロックに何を書けばいいのかわからない。

SQLCm.CommandText = SQL
SQLCm.ExecuteNonQuery()
↑Tryブロックにこれらを入れると、全部が通る部分だからいいかと思ったんですが…。

###発生している問題・エラーメッセージ

以下のコードを書いたところ、SQLCm.ExecuteNonQuery()を通るすべてが例外処理に引っかかってダイアログが出る。
(普通に考えたら更新データはSQL文を実行しようとしているので、全部通るのは当たり前ですよね…。)

###該当のソースコード

VB.NET

1 Try 2 SQLCm.ExecuteNonQuery() 3 4 Catch ex As Exception 5 6 MessageBox.Show("エラーが発生しました。", "エラーが発生しました", MessageBoxButtons.OK, MessageBoxIcon.Error) 7 8 End Try 9 10 '●更新実行 11 12 SQLCm.CommandText = SQL 13 Cn.Open() 14 SQLCm.ExecuteNonQuery() 15 Cn.Close() 16

###試したこと
ここまでのコードで入力エラーダイアログを出したりNULL置換処理をしたりして考え得るほとんどのエラーは回避していると思うのですが、それでも万が一エラーが発生してしまったときのために
取り敢えず、エラーを示すダイアログを出す処理をしたいと考えています(エラーにかかった後の処理はそれができてから考えようと思っています)。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

全体像が見えないので的外れでしたらすみません。

こういう処理が書きたかったのでしょうか?

'●更新実行 SQLCm.CommandText = SQL Try Cn.Open() SQLCm.ExecuteNonQuery() Cn.Close() Catch ex As SQLException '例えばSQLServerのエラー Cn.Close() MessageBox.Show("SQLエラーが発生しました。(" & ex.Code & ":" & ex.Message & ")", "エラーが発生しました", MessageBoxButtons.OK, MessageBoxIcon.Error) Catch ex As Exception Cn.Close() MessageBox.Show("エラーが発生しました。", "エラーが発生しました", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try

Oracleなら
Catch ex As OracleException
のような記述になります。

SQLExcceptionのCatch部分を記述しなかった場合、SQLServerのエラーもExceptionのほうでCatchされることになります。

投稿2016/08/09 03:50

jawa

総合スコア3013

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yyy

2016/08/09 04:16

回答いただきありがとうございます。 たぶん仰っていただいた通りかと思います! そもそもTry~Catchの形(どこに入れて使用するのか)がわかっていなかったようです…。 別々に書いていたTry~Catchと更新実行は纏めるべきなのですね?考えてみたらSQLCm.ExecuteNonQuery()を2回するのはおかしいですよね…。 SQLServerのエラーなんてものもあるのですね、そちらも今後使う機会があるかもしれないので調べてみます。 エラーの処理が1通りしかない場合はCatchを1回Exceotionで処理するように書いてあげればいいのですね!
yyy

2016/08/09 04:44

追加で質問させていただきたいのですが、2つ目のCatchで Catch ex As Exception Cn.Close() と、 Cn.Close()が書いてあるのは何故でしょうか? これを書かなくてもCloseするように思えてしまうのですが…。
jawa

2016/08/09 05:13 編集

Tryの中のSQLCm.ExecuteNonQuery()の行でエラーが発生した場合、次の行Cn.Close()を処理せずにCatchに飛ぶことになります。 この時Close漏れが発生するのを防ぐためにCatch内でもCloseしています。 Openに失敗してCatchに入った場合もCloseが行われることになりますが、Openしていない状態でCloseしても問題ないためこのような記述がよく行われます。 その他、必要に応じてですがRollBackもCatch内で書かれることが多いです。
yyy

2016/08/09 05:38

そういうことなのですね、覚えておこうと思います。 ありがとうございました!
Panzer_vor

2016/08/09 10:44

横から失礼致します。 エラーあり・なしに関わらず必ず実施したい処理を記載するのでしたら、try〜catch〜finallyの構文が便利です。 finally句はcatch句に入ろうが入らないが必ず実行されます。そのため特にcatch句が分かれる場合で、最後に必ず実施すべき処理がある場合はfinally句を使うことをお勧めします。 また.NETでは必ずリソースの破棄(Dispose)を保証する機能としてUsing句がサポートされてるのでご参考までに。 http://dobon.net/vb/dotnet/beginner/calldispose.html
guest

0

具体的なクラスがわからないので推測ですが、
一般的にデータベース絡みの処理(接続、クエリの発行など)でエラーが発生すると、それ専用のExceptionクラスがスローされます。
(例:Sql〜シリーズのクラスならSqlExceptionをスロー)

そのため、例外がスローされた時点ではどういう原因でのエラーかの判断が出来ません。

ですので一般的には、
Catch句で例外を補足した後に、
その例外クラスのエラーコードを調べることで原因の切り分けを行います。

また、質問者さんはSQL構文誤りのある場合のみ例外としたいということですが、

  • 実行したSQLが指定した応答待機時間を超えタイムアウトした
  • SQL実行時DB接続がクローズしていた

上記のようなケースも例外として適切に取り扱う必要があるため、
これらがCatchされること自体は問題ではないと思います。

強いて言うならデータベース絡みのエラーを明示的に扱う意味で、
特定の例外(SqlExceptionなど)を取り扱うCatch節を一つ追加し、
固有処理を行うようにしてあげると良いでしょう。

###追記
一応簡単に例示しときます

VB.NET

1Try 2 '●更新実行 3 Cn.Open() 4 SQLCm.CommandText = SQL 5 SQLCm.ExecuteNonQuery() 6 7Catch ex As SqlException 8 ' ex.Numberで一番最初のエラーコードが取れる(SqlExceptionの場合) 9 MessageBox.Show("データベース関連エラー発生。", "エラーが発生しました", MessageBoxButtons.OK, MessageBoxIcon.Error) 10 11Catch ex As Exception 12 MessageBox.Show("その他のエラーが発生。", "エラーが発生しました", MessageBoxButtons.OK, MessageBoxIcon.Error) 13 14Finally 15 Try 16 ' エラーがある場合でもDB切断は必ず行う 17 Cn.Close() 18 Catch ex As Exception 19 ' DB切断もこけよった場合…… 20 End Try 21End Try

投稿2016/08/09 03:27

編集2016/08/09 05:24
Panzer_vor

総合スコア1636

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yyy

2016/08/09 04:25

回答いただきありがとうございます。 そうですね。質問にも軽く書きましたが、以前にも入力時にNULLが認められなかったり、数字限定セルに文字列を入れてエラーになったりしました。後者に関してはDataErrorイベントで対処して、先にデータを飛ばさずにエラー表示がされるように作ってあります。 想定できるエラーは個別処理をしておりますので、今回はそれらを超えてCatchされてしまったエラーすべてに対しての処理を行いたいという意味でした。 「SQL構文誤りのある場合のみ例外としたい」というように質問には書かせていただきましたが、書き方が悪かったようです。普通はそんなよくわからない書き方・ケースの書き方はしないのですね。そのあたりも含め勉強します。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問