- PR -

VBからストアド実行時SQL Server上のエラーを制御できないか?

1
投稿者投稿内容
マイルドセブンFK
会議室デビュー日: 2008/03/18
投稿数: 3
投稿日時: 2008-03-18 20:55
読者各位

初めて投稿します。
標記の件ご存知の方がいらしたらご教授をお願いします。
詳細を下記に記述します。

【開発環境】Microsoft Visual Studio 2005 Professional Edition
【開発言語】Visual Basic 2005
【DB】SQL Server 2005

VBからストアドを実行する際に、
呼び出そうとするストアドが実際には存在しない場合や、
ストアドは存在するものの受け渡す引数の数が合っていない場合に
SQL Serverから下記のようなメッセージが返ってきます。
「ストアド プロシージャ '[ストアド名]' が見つかりませんでした。」
「プロシージャまたは関数 [ストアド名] に指定された引数が多すぎます。」

一方で、VB側でストアド処理本体のエラーの制御をするために、
戻り値(ReturnCD)やエラーサブレベル(ErrorSubLevel)を利用した
エラー処理を作成しているのですが、
上記の場合はストアドそのものが実行されないためストアド内から
ReturnCDやErrorSubLevelに異常値を入れて値を返すことができません。

上記のように、ストアドが実行されず、かつSQL Server上でエラーと判断できる時に
VB上でエラーと判断してエラー処理部に制御を移すようなことは
できないのでしょうか(VBのサンプルコードを下記に記します)?
---(サンプルコードここから)------------------------------
Dim transaction As SqlTransaction = Nothing
Try
connection.Open()
transaction = connection.BeginTransaction()
command.Transaction = transaction

'ストアドプロシージャ実行
logger.Info("ストアドプロシージャ実行START-->")
command.ExecuteNonQuery()
logger.Info("ストアドプロシージャ実行END--<")

'ここでSQL Serverのエラーを取得する方法はないのか?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

transaction.Commit()
Catch ex As Exception
'ここでストアドが実行できない場合の例外処理の記述は可能なのか?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Finally
connection.Close()
End Try
---(サンプルコードここまで)------------------------------

以上です。どなたか良い情報をお持ちでしたら
何卒ご回答をよろしくお願いします。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2008-03-18 22:36
ご質問がよく理解できないのですが、これは、
「ストアドプロシージャがない場合でも例外が発生しない。どうにかして判別する方法はないか」
というご質問なのでしょうか?
マイルドセブンFK
会議室デビュー日: 2008/03/18
投稿数: 3
投稿日時: 2008-03-19 09:29
返信ありがとうございます。

>「ストアドプロシージャがない場合でも例外が発生しない。どうにかして判別する方法はないか」
端的に言えばご指摘の通りです。
ただ、ストアドプロシジャが無い場合だけではなく、引数エラーといった
ストアドプロシジャ実行以前の状態を把握する仕組みはないかと言うことが知りたいところです。
ラフィン
会議室デビュー日: 2007/11/23
投稿数: 5
投稿日時: 2008-03-19 10:38
引用:

マイルドセブンFKさんの書き込み (2008-03-19 09:29) より:

>「ストアドプロシージャがない場合でも例外が発生しない。どうにかして判別する方法はないか」
端的に言えばご指摘の通りです。


 本当に「ご指摘の通り」ですか?

 Catch のところではどういう処理をされているんですか?
 ストアドプロシージャがない場合でもそこを通らないんですね?
テッテ
ベテラン
会議室デビュー日: 2008/03/16
投稿数: 91
投稿日時: 2008-03-19 11:31
念のため検証してみました。
Windows フォームで、コードは以下。

コード:

Dim con As SqlConnection = Nothing
Try
con = New SqlConnection("接続文字列")
con.Open()

Dim command1 As SqlCommand = New SqlCommand("AAA", con)
command1.CommandType = CommandType.StoredProcedure

command1.ExecuteNonQuery()

MessageBox.Show("正常終了")

Catch ex As SqlException

MessageBox.Show(ex.Message)

Finally

If con IsNot Nothing Then

con.Close()

End If

End Try



当然ですが「AAA」という名前のストアドプロシージャは作っていません。
実行すると、メッセージボックスに
「ストアド プロシージャ 'AAA' が見つかりませんでした。」と表示されました。
デバッガで見ると「command1.ExecuteNonQuery()」の箇所で例外がスローされているようです。

このことから考えて、質問者さんのコードでも、本当にストアドプロシージャがなければ
Catch ex As Exception のブロックに入ってくると思いますが…

#環境を書き忘れたので以下追記

Visual Studio 2005 Professional Edition / SQL Server 2005 Express Edition です。


[ メッセージ編集済み 編集者: テッテ 編集日時 2008-03-19 11:33 ]
マイルドセブンFK
会議室デビュー日: 2008/03/18
投稿数: 3
投稿日時: 2008-03-19 15:54
読者各位

返信ありがとうございます。
テッテさんの情報大変参考になりました。

今回の処理を改めて見直した結果、
既出のサンプルコードのさらに前(上)に
connection.FireInfoMessageEventOnUserErrors = True
という一文がありました。

msdnで調べた結果、このプロパティをTrueにすると
>例外として処理されていたエラーが InfoMessage イベントとして処理されるようになります。
という動きになるようです(つまり例外処理として扱われなくなります)。
実際に上記プロパティを指定しないで実行すると
今回の問題はTry..Catchで取得できるようになりました。

前任から引き継いだプログラムでしたが
私の方で上記部分を見落としていたようです。

情報をお寄せ頂いた方々ありがとうございました。
本件はこれで解決です。
1

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