【问题标题】:Stored procedure returns -1 after creating user创建用户后存储过程返回-1
【发布时间】:2018-01-29 21:04:52
【问题描述】:

创建用户时遇到问题。当我创建一个新用户时,我的 proc 返回 -1,但它必须返回用户 ID。

存储过程运行良好,正在向表中插入数据,但返回-1

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[sp_CreateUser]
    @Address nvarchar(300),
    @BirthDay date,
    @Email nvarchar(64),
    @FullName nvarchar(300),
    @Image nvarchar(2000),
    @Password nvarchar(512),
    @PhoneNumber nvarchar(10),
    @Sex nvarchar(3),
    @RoleId int
AS
BEGIN TRY
    SET NOCOUNT ON;

    INSERT INTO [dbo].[Users] ([Address], [BirthDay], [Email], [FullName], [Image], [Password], [PhoneNumber], [Sex], [RoleId])
    VALUES (@Address, @BirthDay, @Email, @FullName, @Image, @Password, @PhoneNumber, @Sex, @RoleId)
    RETURN 0    
END TRY
BEGIN CATCH
    RETURN -1
END CATCH

我在我的存储库方法中有创建:

public async Task<int> Create(User user)
{
    string sql = $"sp_CreateUser @BirthDay = '{user.BirthDay.ToString("yyyy-MM-dd")}', @Email = '{user.Email}', @FullName = '{user.FullName}', @Password = '{user.Password}', @RoleId = {user.RoleId}, @Address = '{user.Address}', @Image = '{user.Image}', @PhoneNumber = '{user.PhoneNumber}', @Sex = '{user.Sex}'";
    int result = await _db.Database.ExecuteSqlCommandAsync(sql);
    return result;
}

【问题讨论】:

  • 您的 sql 语句返回 0(如果有效)或 -1(如果无效)。这与 C# 几乎没有关系。您需要修复您的 SQL 语句
  • 如果你想返回这样的值(只是添加了用户 ID),唯一可靠的方法是输出语法 (docs.microsoft.com/en-us/sql/t-sql/queries/…)。任何其他方法都容易出现问题或竞争条件。正如 oppassum 所说,这是一个 SQL 问题,而不是 C# 问题。
  • 谢谢,我会试试你的建议,也许他们会帮助我)
  • 在您的 executesql 命令行上放置一个断点并在管理工作室中运行您的 sql profiler。我怀疑您的单引号被重复了,并且您在实际 sql 语句中的参数值看起来像带有 2 个单引号的 ''2018-01-29''。还要检查您传递的所有值的长度。如果它们超出了您定义的限制,它将在查询中出错并返回 -1。
  • 你需要使用@Return_Value输出sql参数,不知道你用EF是怎么做的。对于“正常”SqlCommandExecuteNonQuery 本身的返回值是影响的行数,除了Set NoCount On 在这种情况下-1SqlCommand 返回。我想这是 EF 的确切情况,因为底层 SQL 提供程序是相同的。如果我要在没有 EF 并使用 ExecuteNonQuery 的情况下运行它,除了结果为 -1 之外,我认为这在技术上不是错误...

标签: c# sql-server stored-procedures asp.net-core entity-framework-core


【解决方案1】:

在您的 Try/Catch 中尝试使用以下查询。

   SELECT   
        ERROR_NUMBER() AS ErrorNumber  
       ,ERROR_MESSAGE() AS ErrorMessage;  

它将为您提供有关触发 catch 块执行的更多信息

可以在此处找到有关此检索错误信息的更多信息。

https://docs.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql

【讨论】:

    【解决方案2】:

    解决了!

    我已经使用 SqlParameter 添加了返回参数,现在一切正常。

    public async Task<int> Create(User user)
            {
                var param = new SqlParameter
                {
                    ParameterName = "@CreatedId",
                    SqlDbType = SqlDbType.Int,
                    Direction = ParameterDirection.Output
                };
    
                string sql = $"exec @CreatedId = sp_CreateUser @BirthDay = '{user.BirthDay.ToString("yyyy-MM-dd")}', @Email = '{user.Email}', @FullName = '{user.FullName}', @Password = '{user.Password}', @RoleId = {user.RoleId}, @Address = '{user.Address}', @Image = '{user.Image}', @PhoneNumber = '{user.PhoneNumber}', @Sex = '{user.Sex}'";
                int result = await _db.Database.ExecuteSqlCommandAsync(sql, param);
                return (int)param.Value;
            }
    

    或者另一种方式是在存储过程中设置

    SET NOCOUNT OFF
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-09
      • 2014-06-18
      • 1970-01-01
      • 1970-01-01
      • 2014-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多