【问题标题】:Stored procedure always returns 0, even if the process inside works fine存储过程总是返回 0,即使里面的过程工作正常
【发布时间】:2021-06-24 01:39:30
【问题描述】:

我正在编写一个用于删除数据的存储过程。只有当没有字段连接到该程序时,它才应该删除该程序。

我的逻辑是先按Id对与TA_Program相关的列进行计数,如果count返回0则删除程序,如果返回-3则提示字段连接,否则提示互联网连接。

但是,即使删除过程本身运行良好,存储过程也总是返回 0,所以我所做的失败警报总是会出现。

我阅读了几篇关于@@ROWCOUNTdeleteROWCOUNT 之间关系的帖子,但每次尝试都返回 0,没有别的。你能帮我解决这个问题吗?

这是我的存储过程以及它的查询方式。

CREATE PROCEDURE SP_Delete_Program_By_Id 
    (@Id int)
AS
BEGIN
    DECLARE @FieldCount AS int
    DECLARE @ResultCount AS int
    
    -- count FieldId Where Id = @Id
    SELECT @FieldCount = (SELECT COUNT(*) FROM TA_Field (Nolock) WHERE Id = @Id)
       
    -- if no Field is connected, delete program
    IF @FieldCount = 0
    BEGIN
        DELETE FROM TA_Program
        WHERE Id = @Id

        SELECT @FieldCount = (SELECT COUNT(*) FROM TA_Program (Nolock) WHERE Id = @Id)

        IF @FieldCount = 0
            SELECT @ResultCount = 1
        ELSE
            SELECT @ResultCount = -1
    END
    ELSE
        SELECT @ResultCount = -3

    RETURN @ResultCount
END

C#代码:

    public static int DeleteProgram(Program obj)
    {
        int result = -1;

        // Sort is for determining db id and pw stored 
        using (var db = DBConnectionHelper.GetConnection(Sort.Program))
        {
            var param = new DynamicParameters();
            //param.Add("@FieldId", obj.FieldId);
            param.Add("@Id", obj.Id, dbType: DbType.Int32);
            result = db.Query<int>("APISP_Delete_Program_By_Id", param: param, commandType: CommandType.StoredProcedure).SingleOrDefault<int>();
        }

        return result;
        // this always returns 0
    }

    [HttpPost]
    public APIResult DeleteProgram(string session, Program program)
    {
        int deleteResult = ProgramsDbHelper.DeleteProgram(program);

        if (deleteResult == 1)
        {
            result.ResultCode = 1;
            return result;
        }

        if (deleteResult == -3)
        {
            result.ResultCode = -3;
            return result;
        }            

        return result;
    }

【问题讨论】:

  • 您需要向我们展示您是如何调用 SP 并访问返回值的。
  • 你好像不是要添加返回参数?这就是您访问返回值的方式。对于 SingleOrDefault,您需要 select @ResultCount 而不是返回它。
  • 停止使用nolock 向您的代码发送垃圾邮件。使用不推荐使用的语法使情况变得更糟。
  • 您定义的过程和您在 C# 中调用的过程名称不同:APISP_Delete_Program_By_Id(程序调用)、SP_Delete_Program_By_Id(过程定义)
  • 请不要在存储过程前加上 sp_ 前缀,它实际上并不代表“存储过程”。 SP_ 被系统存储过程使用 - 请参阅stackoverflow.com/questions/42640852/…

标签: sql sql-server tsql stored-procedures


【解决方案1】:

您的程序存在许多问题

  • 您的主要问题:使用RETURN 而不是SELECT
  • 应避免使用NOLOCK
  • 应避免使用sp_ 前缀
  • 假设TA_FieldTA_Program 的外键,逻辑没有意义:因为你没有事务并且没有使用HOLDLOCK, UPDLOCK,另一个用户可以插入到TA_Program 中在您的SELECT COUNTDELETE 之间,此时您将收到一个错误,并且该过程的其余部分将不会运行。如果没有人插入,那么额外的SELECT COUNT 是没有用的,因为数据没有改变。
  • 您实际上不需要任何逻辑,因为您可以将其组合到 DELETE 语句中(无论如何,每个语句都在其自己的事务中)。

所以你的程序应该是这样的:

CREATE PROCEDURE Delete_Program_By_Id 
    (@Id int)
AS

SET NOCOUNT ON;

DELETE FROM TA_Program
WHERE Id = @Id
  AND NOT EXISTS (SELECT 1
      FROM TA_Field
      WHERE Id = @Id);
  
SELECT CASE WHEN @@ROWCOUNT > 0 THEN 1 ELSE -3 END;

GO

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 2018-08-13
    • 1970-01-01
    相关资源
    最近更新 更多