You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何通过C#调用存储过程无法更新SQL Server数据表值?

问题:C#执行存储过程无数据变更,SSMS执行正常

通过C#调用存储过程时,数据表ac00中的值没有变化;但在SQL Server Management Studio(SSMS)中直接执行该存储过程,却能正常更新数据。

C# 调用代码

DatabaseLibrary.ParametersClear();

DatabaseLibrary.command.Parameters.Add(new SqlParameter("@guid", SqlDbType.UniqueIdentifier)).Value = formGuid;
DatabaseLibrary.command.Parameters.Add(new SqlParameter("@val", SqlDbType.Float)).Value = (Sumsrc.Net * Convert.ToDouble(ParityTxt.Text));
DatabaseLibrary.command.Parameters.Add(new SqlParameter("@in", SqlDbType.Bit)).Value = input ? 1 : 0;
DatabaseLibrary.command.Parameters.Add(new SqlParameter("@operation", SqlDbType.Bit)).Value = 1;

DatabaseLibrary.ExecuteStoredProcedure(StoredProcedure.AccountUpdate);

存储过程代码

CREATE PROCEDURE [dbo].[AccountUpdate]
    @guid uniqueidentifier,
    @val float,
    @in bit, -- 1 or 0
    @operation bit  -- 1 or 0
AS
BEGIN
    DECLARE @oldVal float

    IF (@in > 0)
    BEGIN
        IF (@operation > 0)
        BEGIN
            SET @oldVal = (SELECT ISNULL(Debit, 0) FROM ac00 WHERE GUID = @guid)

            UPDATE ac00  
            SET [Debit] = (@oldVal + @val) 
            WHERE GUID = @guid
        END
        ELSE
        BEGIN
            SET @oldVal = (SELECT ISNULL(Debit, 0) FROM ac00 WHERE guid = @guid)

            UPDATE ac00  
            SET [Debit] = (@oldVal - @val) 
            WHERE GUID = @guid
        END
    END
    ELSE
    BEGIN
        IF (@operation > 0)
        BEGIN
            SET @oldVal = (SELECT ISNULL(Credit, 0) FROM ac00 WHERE GUID = @guid)

            UPDATE ac00  
            SET [Credit] = (@oldVal + @val) 
            WHERE GUID = @guid
        END
        ELSE
        BEGIN
            SET @oldVal = (SELECT ISNULL(Credit, 0) FROM ac00 WHERE GUID = @guid)

            UPDATE ac00  
            SET [Credit] = (@oldVal - @val) 
            WHERE GUID = @guid
        END
    END
END

排查与解决方法

  • 检查事务提交:SSMS默认自动提交事务,但你的DatabaseLibrary可能开启了事务却未显式提交。查看ExecuteStoredProcedure方法内部逻辑,确保执行完成后调用了事务的Commit()方法。
  • 验证参数有效性:
    1. 在C#代码中打印formGuid、计算后的@val、input的实际值,对比SSMS执行时传入的参数是否完全一致。
    2. 确认formGuid是有效的Guid,没有空值或格式错误,避免WHERE GUID = @guid匹配不到数据行。
    3. 注意float类型精度问题,C#计算后的数值可能和SSMS中输入的存在微小差异,导致更新效果不明显。
  • 优化存储过程逻辑:当前先查询再更新的写法存在并发风险,且冗余代码多,可简化为单条UPDATE语句,避免查询与更新之间的不一致:
    CREATE PROCEDURE [dbo].[AccountUpdate]
        @guid uniqueidentifier,
        @val float,
        @in bit,
        @operation bit
    AS
    BEGIN
        IF (@in = 1)
        BEGIN
            UPDATE ac00
            SET Debit = ISNULL(Debit, 0) + CASE WHEN @operation = 1 THEN @val ELSE -@val END
            WHERE GUID = @guid
        END
        ELSE
        BEGIN
            UPDATE ac00
            SET Credit = ISNULL(Credit, 0) + CASE WHEN @operation = 1 THEN @val ELSE -@val END
            WHERE GUID = @guid
        END
    END
    
  • 跟踪SQL执行:用SQL Server Profiler或扩展事件,捕获C#调用存储过程时的实际执行语句和参数,和SSMS的执行记录对比,定位差异点。

内容的提问来源于stack exchange,提问作者Davied

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 10:25:37