簡體   English   中英

tSQL錯誤“子查詢返回了多個值...”在SqlClient中未引發異常

[英]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

.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();
        }
    }
}

運行此應用程序只是將“完成”寫入控制台。

在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)

替代問題

我發現的其他一些定義也不會拋出異常。

之后的Raiserror

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM