はじめに
.Net 4.0.30319 SP1Rel の SqlClient に問題があり、ストアド プロシージャで次のエラーが発生したときに例外がスローされません。
サブクエリが複数の値を返しました。サブクエリが =、!=、<、<=、>、>= の後にある場合、またはサブクエリが式として使用されている場合、これは許可されません。
これを示す小さなプログラムとストアド プロシージャを作成しました。SQL Server のバージョンは 9.0.4053 です。
コードサンプル
ストアド プロシージャ
create proc test
as
select case (select 1 union select 2) when 1 then 1 else 2 end
.Net コンソール アプリ
using System;
using System.Data;
using System.Data.SqlClient;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
SqlConnection conn = new SqlConnection("<your connection string>");
conn.Open();
SqlCommand cmd = new SqlCommand("test", conn);
cmd.CommandType = CommandType.StoredProcedure;
try
{
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
Console.WriteLine("Finished");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadKey();
}
}
}
このアプリケーションを実行すると、コンソールに「Finished」と表示されます。
SQL Server Management Studio でストアド プロシージャ 'test' を実行すると、結果ペインに次のようなエラーが報告されます。
メッセージ 512、レベル 16、状態 1、手順テスト、行 3 サブクエリが複数の値を返しました。サブクエリが =、!=、<、<=、>、>= の後にある場合、またはサブクエリが式として使用されている場合、これは許可されません。
期待される動作
次の例でストアド プロシージャを置き換えると、予想される System.Data.SqlClient.SqlException が発生します。
レイズエラー
alter proc test
as
raiserror('Not good at all!', 16, 1)
代替問題
私が見つけた他のいくつかの定義も同様に例外をスローしません。
レイズエラー
alter proc test
as
select case (select 1 union select 2) when 1 then 1 else 2 end
raiserror('Not good at all!', 16, 1)
これは、選択ステートメントがストアド プロシージャの実行を停止することを示唆しています。
ゼロで割る
alter proc test
as
select 1/0
私の結論は、SqlClient が tSql バッチのエラー状態を正しく認識していないということです。誰かがこれに遭遇し、解決策を見つけましたか? 私は常に、.Net フレームワークが tSql エラーで例外をスローすることを信頼していました。