Jac*_*kal 8 c# sql-server entity-framework-core-3.1
这返回-1,我如何从存储过程中获取实际返回值?
这是我的存储过程
ALTER PROCEDURE [Production].[Select_TicketQuantity]
@Ticket NVARCHAR(25),
@Reference NVARCHAR(20)
AS
BEGIN
declare @SQL nvarchar (4000)
SET @SQL = 'select QARTCOL as Quantidade from D805DATPOR.GCARCCR1 where NCOLGIA = ' + @Ticket + ' AND NARTCOM = ''' + @Reference + ''''
SET @SQL = N'select CONVERT(int,Quantidade) as Quantidade from OpenQuery(MACPAC, ''' + REPLACE(@SQL, '''', '''''') + ''')'
PRINT @SQL
EXEC (@SQL)
END
Run Code Online (Sandbox Code Playgroud)
C# 代码
int? quantity= 0;
try
{
quantity= await _context.Database.ExecuteSqlRawAsync("EXEC Production.Select_TicketQuantity @p0, @p1", parameters: new[] { ticket, reference});
}
catch (Exception ex)
{
_logger.LogError($"{ex}");
return RedirectToPage("Index");
}
Run Code Online (Sandbox Code Playgroud)
ExecuteSqlRawAsyncthe number of rows affected插入、更新和删除返回(-1 表示选择)。
如果你不想改变你的 SP 来引入output parameter你可以使用SqlCommand. SqlCommand.ExecuteScalar()返回The first column of the first row in the result set:
using (var cmd = _context.Database.GetDbConnection().CreateCommand()) {
cmd.CommandText = "[Production].[Select_TicketQuantity]";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
if (cmd.Connection.State != System.Data.ConnectionState.Open) cmd.Connection.Open();
cmd.Parameters.Add(new SqlParameter("Ticket", ticket));
cmd.Parameters.Add(new SqlParameter("Reference", reference));
quantity = (int)cmd.ExecuteScalar();
}
Run Code Online (Sandbox Code Playgroud)
您需要创建并使用输出参数,在您的情况下:
ALTER PROCEDURE [Production].[Select_TicketQuantity]
@Ticket NVARCHAR(25),
@Reference NVARCHAR(20),
@Quantity int output
AS
BEGIN
declare @SQL nvarchar(4000) = 'select QARTCOL as Quantidade from D805DATPOR.GCARCCR1 where NCOLGIA = ''' + @Ticket + ''' AND NARTCOM = ''' + @Reference + ''''
select @Quantity = CONVERT(int, Quantidade)
from OpenQuery(MACPAC, @SQL)
END
Run Code Online (Sandbox Code Playgroud)
然后在 C# 中:
int? quantity = 0;
var ticketParam = new SqlParameter("Ticket", ticket);
var referenceParam = new SqlParameter("Reference", reference);
var quantityParam = new SqlParameter("Quantity") { Direction = ParameterDirection.Output };
try
{
await _context.Database.ExecuteSqlRawAsync("EXEC Production.Select_TicketQuantity @Ticket, @Reference, @Quantity output", new[] { ticketParam, referenceParam, quantityParam });
quantity = Convert.ToInt32(quantityParam.Value);
}
catch (Exception ex)
{
_logger.LogError($"{ex}");
return RedirectToPage("Index");
}
Run Code Online (Sandbox Code Playgroud)
添加到AlbertK已经编写的内容中,但使用ExecuteSqlRaw/ ExecuteSqlRawAsync。
OUTPUT parameter最好的选择是在您的存储过程中使用。
想象一个场景,需要从a读取StatusCode :stored procedure
CREATE PROCEDURE dbo.spIfUserExists (
@Username VARCHAR(120),
@StatusCode INT OUTPUT,
) AS
BEGIN
IF EXISTS (SELECT * FROM dbo.[Users] WHERE Username=@Username)
SET @StatusCode = 1;
ELSE
SET @StatusCode = 0;
END
Run Code Online (Sandbox Code Playgroud)
您实际上并没有返回任何内容,而是将一个整数(INT)分配给output parameter外部可用的。
在您的 C# 代码中,您需要SQLParameter使用.output parameterstored procedure
SqlParameter StatusCode = new SqlParameter
{
ParameterName = "@StatusCode",
SqlDbType = System.Data.SqlDbType.Int,
//Direction of this parameter is output.
Direction = System.Data.ParameterDirection.Output
};
Run Code Online (Sandbox Code Playgroud)
最后,ExecuteSqlRawAsync使用 SP 所需的参数执行。
其中@p0,@p1..@pn指示存储过程的位置参数。
string Username = "MyRandomUsername";
using (var ctx = new UsersDbContext())
{
await ctx.Database.ExecuteSqlRawAsync(
"spIfUserExists @p0, @StatusCode OUT",
parameters: new object[] {
Username,
StatusCode,
});
}
//StatusCode now contains the status code from the [spIfUserExists].
Console.WriteLine(Convert.ToInt32(StatusCode.Value));
Run Code Online (Sandbox Code Playgroud)
输出参数不需要像普通参数那样的位置参数,例如Username. 因此,您不需要传递@p[n]到OUTPUT arguments,而只需将它们提供给parameters列表。
如果您要使用ExecuteSqlRaw. 您只需删除await关键字即可同步运行ExecuteSqlRaw。
您的存储过程中可以有多个output parameter具有不同数据类型的存储过程。您只需要遵循相同的模式即可。
| 归档时间: |
|
| 查看次数: |
12217 次 |
| 最近记录: |