我有一個從 C# 代碼呼叫的舊存盤程序,我發現它拋出了類似于這個問題中提到的例外。
就我而言,我有一個默認引數和一個輸出引數,如下所示:
@ReturnVal BIGINT OUTPUT,
@var FLOAT = NULL
呼叫此存盤程序時,我沒有從 C# 代碼中傳遞默認引數。
我可以通過在輸出引數之后移動默認引數來解決這個問題,并且它按預期作業。
@var FLOAT = NULL,
@ReturnVal BIGINT OUTPUT
但我想知道這背后的原因。傳遞引數順序有什么標準嗎?我還沒有找到任何關于它的官方檔案。
請在 C# 代碼下方找到,我正在使用 Dapper。
string sql = "EXEC [mySP] @ReturnVal OUT";
DynamicParameters dynamicParamaters = new DynamicParameters(new { });
dynamicParamaters.Add(@ReturnVal, null, parameter.DbType, ParameterDirection.Output, 0);
int returnVal = _connection.ExecuteScalar<int>(sql, dynamicParams)
uj5u.com熱心網友回復:
也許退后一步,在 SSMS 中嘗試一些事情。這是您的存盤程序的簡化版本:
CREATE PROC dbo.mySP (@var FLOAT = NULL, @ReturnVal BIGINT OUTPUT)
AS
select @var as var
set @ReturnVal = 2
GO
您的 c# 代碼將最終生成一些類似于此的 TSQL:
DECLARE @ReturnVal BIGINT
EXEC dbo.MySP @ReturnVal OUT
這會導致錯誤:“形式引數“@var”未宣告為 OUTPUT 引數,但在請求的輸出中傳遞了實際引數”
這是因為在呼叫中沒有指定引數名稱,引數是按位置傳遞的。因此,“@ReturnVal OUT”作為存盤程序的第一個引數傳遞給 sqlserver(存盤程序的第一個引數實際上是 @var)。
避免該問題的一些可能選項:
選項1,按位置傳遞引數,并指定所有引數:
DECLARE @ReturnVal BIGINT
EXEC dbo.MySP default, @ReturnVal OUT
select @ReturnVal as ReturnVal
因為存盤程序中定義的第二個引數(@ReturnVal)是強制傳遞的,所以使用關鍵字“default”告訴sqlserver使用存盤程序中定義的默認引數值作為第一個引數。
(請注意,您將存盤程序定義中的引數順序更改為:
CREATE PROC dbo.mySP (@ReturnVal BIGINT OUTPUT, @var FLOAT = NULL)
作業,因為第二個引數 @var 是可選的,所以你不必傳遞它。
IE
EXEC dbo.MySP @ReturnVal OUT
和
EXEC dbo.MySP @ReturnVal OUT, default
是等價的。)
選項 2,按名稱傳遞引數,并指定所有引數:
DECLARE @ReturnVal BIGINT
EXEC dbo.MySP @var = default, @ReturnVal = @ReturnVal OUT
select @ReturnVal
注意,在“@ReturnVal = @ReturnVal OUT”中,左邊的“@ReturnVal”指定了存盤程序的引數名稱,右邊的??“@ReturnVal”指定了你的區域變數的名稱,它也恰好被稱為@ ReturnVal 在這種情況下。
選項 3,按名稱傳遞引數。在存盤的程序定義中省略具有默認值的引數:
DECLARE @ReturnVal BIGINT
EXEC dbo.MySP @ReturnVal = @ReturnVal OUT
select @ReturnVal
我建議按名稱傳遞引數,因為它通常會使您的代碼更加健壯。要更清楚地查看從您的 c# 代碼生成的 TSQL,您可以執行 SQL Server Profiler 跟蹤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/530300.html
下一篇:SQL計算每小時銷售額
