[英]tSQL error “Subquery returned more than 1 value…” does not throw an exception in SqlClient
我在.Net 4.0.30319 SP1Rel中存在SqlClient的問題,當我的存儲過程執行以下錯誤時,不會引發任何異常:
子查詢返回的值超過1。 當子查詢遵循=,!=,<,<=,>,> =或將子查詢用作表達式時,不允許這樣做。
我創建了一個小程序並存儲了proc來演示這一點。 SQL Server版本是9.0.4053。
create proc test
as
select case (select 1 union select 2) when 1 then 1 else 2 end
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();
}
}
}
運行此應用程序只是將“完成”寫入控制台。
在de SQL Server Management Studio中運行存儲過程“ test”將在結果窗格中報告錯誤,例如:
消息512,級別16,狀態1,過程測試,第3行子查詢返回的值大於1。 當子查詢遵循=,!=,<,<=,>,> =或將子查詢用作表達式時,不允許這樣做。
通過以下示例替換存儲的proc,將得到預期的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錯誤上引發異常。
感謝馬丁的幫助和迅速的評論,我找到了造成這種奇怪行為的原因。
過去,一位程序員在測試中將讀取的內容包裝在讀取器上,以查看是否有任何行,如下所示:
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
if (reader.HasRows)
{
while (reader.Read()) { /* Do Something */ }
}
我不知道為什么,因為沒有行時,read()方法在第一次調用時將返回false。
無論如何,當tSQL中發生錯誤時,HasRows屬性返回false,並且從未調用過Read()方法。 因此,SQL錯誤不會向SqlClient公開,也不會引發任何異常。
您可以在ExecuteReader之后,無論是否測試HasRows將此代碼段添加到示例項目中,然后查看效果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.