簡體   English   中英

如何從存儲過程 EF Core 3.1 中獲取多個 OUTPUT 參數

[英]How to get Multiple OUTPUT parameters from stored procedure EF Core 3.1

我一直在嘗試修改這里接受的答案該答案似乎利用了RelationalDataReader ,以便從產品所有者希望盡可能多的數據庫驅動的 API 中獲取某些計算日期的 2 個 OUTPUT 參數。

我有一個存儲過程,它根據我存儲在表中的 SQL 查詢計算開始和結束日期,以便他們添加另一個日期范圍所要做的就是將它添加到表中,其余的將在 UI 上就位和管道的其余部分。

RDFacadeExtensions 類的第一部分是相同的,但我認為我可以簡單地添加更多參數並將它們取回,但我似乎遺漏了一些東西。

var ID = new SqlParameter("ID", 5)
{
    Direction = ParameterDirection.Input,
    DbType = DbType.Int32,
    Size = 500
};

var _beginDate = new SqlParameter("BeginDate", "")
{
    Direction = ParameterDirection.Output,
    DbType = DbType.String,
    Size = 500
};

var _endDate = new SqlParameter("EndDate", "")
{
    Direction = ParameterDirection.Output,
    DbType = DbType.String,
    Size = 500
};

這一切似乎很正常,然后我執行以下操作:

string begin;
string end;
var sql = $"exec [dbo].[GetDateRange] @ID, @BeginDate OUTPUT, @EndDate OUTPUT";

using (var dr = context.Database.ExecuteSqlQuery(sql, ID, _beginDate, _endDate))
{
    while (dr.DbDataReader.Read())
    {
        var thing = dr.DbDataReader[0].ToString();
    }
    dr.DbDataReader.Close();
    begin = _beginDate.Value.ToString();
    end = _endDate.Value.ToString();
}

在使用結束之前,我短暫地獲得了第一次約會,但我似乎永遠無法獲得第二次約會。 一旦數據讀取器關閉,我也有空字符串。

如果重要的話,我的存儲過程就是這樣:

    @ID INT,
    @BeginDate DATE OUTPUT,
    @EndDate DATE OUTPUT
BEGIN
    SET NOCOUNT ON;
    DECLARE @Query1 NVARCHAR(1000)
    DECLARE @Query2 NVARCHAR(1000)

    SELECT @Query1 = BeginDate,
           @Query2 = EndDate 
    FROM DateRange 
    WHERE ID = @ID
    
    DECLARE @ParmDefinition1 NVARCHAR(50) = N'@BeginDateOUT DATE OUTPUT';
    DECLARE @ParmDefinition2 NVARCHAR(50) = N'@EndDateOUT DATE OUTPUT';

    EXEC sp_executesql @Query1, @ParmDefinition1, @BeginDateOUT = @BeginDate OUTPUT
    EXEC sp_executesql @Query2, @ParmDefinition2, @EndDateOUT = @EndDate OUTPUT
END

或者也許我的存儲過程是問題所在。 我有一個約會,但只能保持很短的時間。 sp_executesql 的問題在於它必須轉到 OUTPUT 參數,而且除了 INT 變量之外,我不能將結果分配給任何東西。 我需要表中存儲代碼的兩個日期。

如果有辦法做到這一點,並且只返回本質上相當於一個小表結果的內容,那將是理想的。

感謝任何可以為我指明正確方向的人。

因此,至少在 ADO 中,如果您不關閉數據讀取器,您將永遠無法取回您的輸出參數。 在您的示例中,這應該足以滿足您的需求:

    string begin;
    string end;
    var sql = $"exec [dbo].[GetDateRange] @ID, @BeginDate OUTPUT, @EndDate OUTPUT";

    using (var dr = context.Database.ExecuteSqlQuery(sql, ID, _beginDate, _endDate))
    {
        while (dr.DbDataReader.Read())
        {
            var thing = dr.DbDataReader[0].ToString();
        }
        dr.DbDataReader.Close();
        begin = _beginDate.Value.ToString();
        end = _endDate.Value.ToString();
    }

然而, 這里提到了一個有趣的解決方案,它似乎可以解決您的痛點。

所以看起來我不需要使用 sp_executesql 也不需要任何 OUT 參數。

因此,我將存儲過程更改為此,並對表中保存的底層查詢進行了細微更改,以刪除其中的選擇,從而基本上允許在存儲過程中構建 sql。

ALTER PROCEDURE [dbo].[GetDateRange] 
@ID INT

AS BEGIN SET NOCOUNT ON; DECLARE @Query1 NVARCHAR(1000) DECLARE @Query2 NVARCHAR(1000) SELECT @Query1 = BeginDate,@Query2 = EndDate FROM DateRange WHERE ID = @ID

DECLARE @Test NVARCHAR(1000) = 'SELECT ' + @Query1 + ' AS BeginDate, ' + @Query2 + ' AS EndDate'
EXECUTE (@Test)

結尾

然后我能夠使用現有代碼執行以下操作:

        var ID = new SqlParameter("ID", 1)
        {
            Direction = ParameterDirection.Input,
            DbType = DbType.Int32,
            Size = 500
        };

        DataTable dates = new DataTable();
        var sql = $"exec [dbo].[GetDateRange] @ID";

        using (var dr = context.Database.ExecuteSqlQuery(sql, ID))
        {
                dates.Load(dr.DbDataReader);
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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