![](/img/trans.png)
[英]How to pass multiple parameters to stored procedure on .net core 3.1
[英]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.