[英]Query returns different result from C# then from SSMS
我有一個我無法解釋的奇怪問題
當我從 C# 應用程序運行某個查詢時,它返回的結果與我在 SSMS 中運行它時返回的結果不同,但當我使用參數時返回的結果不同
命令是這樣的
select dbo.fnGetPlaceID('6025', null, null)
從 c# 應用程序運行時返回 -1,從 SSMS 運行時返回 1489
但如果我這樣做
declare @DealerCode varchar(30) = '6025'
declare @RegionCode varchar(50) = null
declare @MerkID int = null
select dbo.fnGetPlaceID(@DealerCode, @RegionCode, @MerkID)
然后它也從 c# 應用程序返回正確的值 1489
那么區別是什么呢?
附加代碼:
CREATE function dbo.fnGetPlaceID(@DealerCode varchar(30), @RegionCode varchar(50), @MerkID int) returns int as
begin
declare @Result int = -1
if @RegionCode = ''
set @RegionCode = null
select @Result = r.RelationID
from relation.tblRelation r
where r.dealercode = @DealerCode
-- in the example of '6025' there is only one row, I checked this
-- So the code below should not be executed
if @@ROWCOUNT <> 1
begin
select @Result = rel.RelationID
from relation.tblRelation rel
left outer join dbo.tblRegionCodes r on rel.RegionCodeID = r.FordRegionCodeID
where rel.dealercode = @DealerCode
and (@RegionCode is null or r.RegionCode = @RegionCode)
and (@MerkID is null or rel.BrandID = @MerkID)
if @@ROWCOUNT <> 1
set @Result = -1
end
return @Result
end
和 c# 中的代碼
FillDataTable(myDataTable, "select dbo.fnGetPlaceID('6025', null, null)")
public void FillDataTable(DataTable table, string SqlText, int commandTimeOut = 300)
{
if (_ConnectionString != null && _ConnectionString != "")
{
using (SqlConnection connection = new SqlConnection(_ConnectionString))
{
OpenConnection(connection, SqlText);
using (SqlCommand command = new SqlCommand(SqlText, connection))
{
command.CommandType = CommandType.Text;
command.CommandTimeout = commandTimeOut;
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
try
{
adapter.Fill(table);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
}
}
}
我試過的
然后我在 sql function 中嘗試了這個改變
alter function dbo.fnGetPlaceID(@DealerCode varchar(30), @RegionCode varchar(50), @MerkID int) returns int as
begin
declare @Result int = -1
if @RegionCode = ''
set @RegionCode = null
select @Result = r.RelationID
from relation.tblRelation r
where r.dealercode = @DealerCode
/*
-- in the example of '6025' there is only one row, I checked this
-- So the code below should not be executed
if @@ROWCOUNT <> 1
begin
select @Result = rel.RelationID
from relation.tblRelation rel
left outer join dbo.tblRegionCodes r on rel.RegionCodeID = r.FordRegionCodeID
where rel.dealercode = @DealerCode
and (@RegionCode is null or r.RegionCode = @RegionCode)
and (@MerkID is null or rel.BrandID = @MerkID)
if @@ROWCOUNT <> 1
set @Result = -1
end
*/
return @Result
end
現在它在 c# 應用程序中確實可以正常工作。
因此,出於某種原因,當我從 c# 應用程序調用此 function 時,@@ROWCOUNT 似乎不等於 1,而當我從 SSMS 調用此 function 時,@@ROWCOUNT 等於 1。
我還沒有證實這一點,但這是我的結論。
問題仍然存在,為什么?
還有為什么當我使用參數時它的工作方式不同?
我已通過將 function 更改為來解決我的問題
select @Count = count(1)
from relation.tblRelation r
where r.DealerCode = @DealerCode
然后使用變量@Count 代替rowcount,但我仍然想對這里發生的事情做一些解釋。
我還檢查了如果找到多行,第一個查詢會發生什么。
因為我將查詢結果放在一個變量中,所以如果找到不止一行,那應該會失敗(我的 function 中的一個錯誤,我知道,我現在已經修復了)
declare @Result int = -1
select @Result = r.RelationID
from relation.tblRelation r
where r.dealercode is null
select @@ROWCOUNT
但是 rowcount 並沒有像我預期的那樣拋出異常,而是只有 4512 的值
編輯
正如@DanGuzman 所建議的,當我將 TSQL_SCALAR_UDF_INLINING 設置為 OFF 時它會起作用
select dbo.fnGetPlaceID('6025', null, null)
OPTION (USE HINT('DISABLE_TSQL_SCALAR_UDF_INLINING'))
編輯 2
如果我這樣做,它也可以在沒有提示的情況下工作ALTER DATABASE [myDataBase] SET COMPATIBILITY_LEVEL = 140;
它是在 150
最后更新
我今天安裝了 CU15,並在兼容級別設置為 150 的情況下再次進行了測試,現在它也可以從 c# 開始正常工作。所以這個解決方案現在得到了確認。
自初始 SQL Server 2019 RTM 版本以來,標量 function 內聯存在許多問題。 安裝最新的累積更新以獲取這些修復程序和其他修復程序。
如果不打補丁,解決方法包括:
OPTION (USE HINT('DISABLE_TSQL_SCALAR_UDF_INLINING'))
USE YourDatabase;ALTER DATABASE SCOPED CONFIGURATION SET TSQL_SCALAR_UDF_INLINING = OFF;
本頁列出最新SQL服務器補丁下載鏈接
關於 C# 代碼和 SSMS 的不同行為,這是由於不同的執行計划。 SSMS 查詢默認指定ARITHABORT ON
session 設置,而 C# 不設置該選項。 不同的 session 設置可能會產生不同的執行計划並使故障排除變得困難。 有關詳細信息,請參閱Erland Sommarskog 的文章。 我要補充一點,SSMS 設置 ARITHABORT 只是為了向后兼容。 在 SQL 2019 世界中,它默認處於打開狀態,因為不再支持數據庫兼容級別 80 (SQL 2000)。 考慮在工具-->選項-->查詢執行-->SQL Server--高級下取消選中 SSMS 中的SET ARITHABORT
選項。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.