QA@IT
«回答へ戻る

回答を投稿

先に紹介した msdn blog の記事に書いてあった方針に合意して、その通りに実装するという前提で回答します。(質問者さんや質問者さんの所属する組織の設計方針/ルール/カンパニーポリシーなどが、それとは違うという場合は話が別ですよ)

【疑問1】
この理解で正しいでしょうか?

OracleException を catch して、そのままにしてしまうという点が違うと思います。

先に紹介した記事の Part 1 の[.NET アプリケーションにおける例外と業務エラーの違い]というセクションをよく読んでください。

OracleException の中には「異常事態」(データベース接続エラーやネットワークエラーで、処理が正しく遂行できない事態)もあるはずですが、そのような例外までキャッチしてユーザーに通知しても、ユーザーとしては何ともできません。また、処理は続けないで終了すべきです。

catch すべきは「業務エラー」の方だけです。記事の例では「業務エラー」を、重複ユーザ ID の登録を例にとって説明していますが、それなら想定内の事態としてユーザーに再入力を求めるなどして処置を継続できます。

その具体的な対応例は Part 2 の[try-catch と try-finally を併用する場合のコード例]のセクションを見てください。

また、「異常事態」で発生した例外の処置については、Part 1 の[例外の処理方法]のセクションを見てください。Windows Forms アプリの場合はそのセクションの「② Windows フォームの場合」のところです。

【疑問2】
更新部分で複数のテーブルに対して処理を行う場合は
UsingでCMD1、CMD2、CMD3等と宣言し、下記のように記述するのはいけないのでしょうか?
やはりCMD1、CMD2、CMD3それぞれにTry-Catchを記述するものなのでしょうか?

何を「業務エラー」として catch するかによると思います。

想定しうる「業務エラー」が、例えば CMD1 でしか起こりえないなら CMD1 だけで良いし、CMD1、CMD2、CMD3 全てで起こりうるなら 3 つまとめて囲えば良いし、いずれでも起こらないなら try/catch そのものが不要です。

なお、【疑問1】に対する答えでも書きましたが、catch したままではダメです。catch したものが「業務エラー」でなければ再スローしてください。

【疑問3】
DB接続時以外の一般エラー
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Sub
これをどこへ書けば正しいのか分からなくなってしまいました。

Exception の中には想定できる「業務エラー」は含まれておらず「異常事態」になるのでは?

であれば、上記の【疑問1】への回答を理解できれば、Exception を catch する必要はない(というより、catch してはいけない)ということが分かりますよね。

上にも書きましたが、「異常事態」で発生した例外の処置については、Part 1 の[例外の処理方法]のセクションを見てください。

また、Using~End Usingで記述するとFainallyは不要だと理解していたのですが、
これも誤った解釈だったのということでしょうか。

確実にコネクションリークを防ぐという目的には、どちらか一方でいいです。詳しくは Part 2 の[IDisposable インタフェースと using ブロックによる try-finally の記述]のセクションを読んでください。

なお、記事では SqlCommand の方は Dispose していませんが、Dispose したほうがいいのは確かなようです。詳しくは以下のページを見てください。まぁ、ほとんど影響はないのかもしれませんが。

SqlCommand の Dispose は呼ぶべきか?
http://surferonwww.info/BlogEngine/post/2013/04/23/whether-to-call-dispose-method-for-sqlcommand-object.aspx

先に紹介した msdn blog の記事に書いてあった方針に合意して、その通りに実装するという前提で回答します。(質問者さんや質問者さんの所属する組織の設計方針/ルール/カンパニーポリシーなどが、それとは違うという場合は話が別ですよ)

>【疑問1】
> この理解で正しいでしょうか?

OracleException を catch して、そのままにしてしまうという点が違うと思います。

先に紹介した記事の Part 1 の[.NET アプリケーションにおける例外と業務エラーの違い]というセクションをよく読んでください。

OracleException の中には「異常事態」(データベース接続エラーやネットワークエラーで、処理が正しく遂行できない事態)もあるはずですが、そのような例外までキャッチしてユーザーに通知しても、ユーザーとしては何ともできません。また、処理は続けないで終了すべきです。

catch すべきは「業務エラー」の方だけです。記事の例では「業務エラー」を、重複ユーザ ID の登録を例にとって説明していますが、それなら想定内の事態としてユーザーに再入力を求めるなどして処置を継続できます。

その具体的な対応例は Part 2 の[try-catch と try-finally を併用する場合のコード例]のセクションを見てください。

また、「異常事態」で発生した例外の処置については、Part 1 の[例外の処理方法]のセクションを見てください。Windows Forms アプリの場合はそのセクションの「② Windows フォームの場合」のところです。


>【疑問2】
> 更新部分で複数のテーブルに対して処理を行う場合は
> UsingでCMD1、CMD2、CMD3等と宣言し、下記のように記述するのはいけないのでしょうか?
> やはりCMD1、CMD2、CMD3それぞれにTry-Catchを記述するものなのでしょうか?

何を「業務エラー」として catch するかによると思います。

想定しうる「業務エラー」が、例えば CMD1 でしか起こりえないなら CMD1 だけで良いし、CMD1、CMD2、CMD3 全てで起こりうるなら 3 つまとめて囲えば良いし、いずれでも起こらないなら try/catch そのものが不要です。

なお、【疑問1】に対する答えでも書きましたが、catch したままではダメです。catch したものが「業務エラー」でなければ再スローしてください。


>【疑問3】
> DB接続時以外の一般エラー
> Catch ex As Exception
> MessageBox.Show(ex.ToString)
> End Sub
> これをどこへ書けば正しいのか分からなくなってしまいました。

Exception の中には想定できる「業務エラー」は含まれておらず「異常事態」になるのでは?

であれば、上記の【疑問1】への回答を理解できれば、Exception を catch する必要はない(というより、catch してはいけない)ということが分かりますよね。

上にも書きましたが、「異常事態」で発生した例外の処置については、Part 1 の[例外の処理方法]のセクションを見てください。

> また、Using~End Usingで記述するとFainallyは不要だと理解していたのですが、
> これも誤った解釈だったのということでしょうか。

確実にコネクションリークを防ぐという目的には、どちらか一方でいいです。詳しくは Part 2 の[IDisposable インタフェースと using ブロックによる try-finally の記述]のセクションを読んでください。

なお、記事では SqlCommand の方は Dispose していませんが、Dispose したほうがいいのは確かなようです。詳しくは以下のページを見てください。まぁ、ほとんど影響はないのかもしれませんが。

SqlCommand の Dispose は呼ぶべきか?
http://surferonwww.info/BlogEngine/post/2013/04/23/whether-to-call-dispose-method-for-sqlcommand-object.aspx