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

如何在SQL Server中同时更新两张表?存储过程修改求助

修正SQL Server库存同步存储过程

我有两张SQL Server表:SERVIS_GON_TABLO(维修发货记录表)和STOK_TABLO(库存表)。当更新SERVIS_GON_TABLO中的产品信息后,需要同步更新STOK_TABLO内两个不同产品的库存。具体场景:

  • 初始操作:将扫码枪发往维修,此时维修地点库存+1、仓库库存-1;
  • 修正操作:因发错产品,需改为发COMPUTER,此时要将扫码枪的仓库库存+1、维修地点库存-1,同时将COMPUTER的仓库库存-1、维修地点库存+1。

我通过GridView将数据导入文本框,尝试用存储过程实现表更新,现有存储过程如下:

ALTER PROCEDURE UPDATE_TABLE
    (@STOCKID NVARCHAR(100),
     @MODELID NVARCHAR(100),
     @QTY INT,
     @FROM NVARCHAR(60),
     @TO NVARCHAR(60),
     @TEDARIKID NVARCHAR(150),
     @TED_TEL NVARCHAR(50))
AS
BEGIN
    DECLARE
         @StockQTY INT,
         @YeniUrunID NVARCHAR(100),
         @Location NVARCHAR(100)

    --This part which I sent to service and update a table(SERVIS_GON_TABLO) 
    UPDATE SERVIS_GON_TABLO 
    SET URUNID = @URUNID,
        MODELID = @MODELID,
        TEDARIKID = @TEDARIKID,
        TEDARIK_TELEFON = @TED_TEL 
    WHERE SERVISID = @ID

    -- Below in other table I try to UPDATE at STOCK_TABLE which I sent to service new STOCK 
    UPDATE STOK_TABLO 
    SET ADET -= @ADET 
    WHERE URUNID = @URUNID AND LOKASYONID = @NEREDEN 

    UPDATE STOK_TABLO 
    SET ADET += @ADET 
    WHERE URUNID = @URUNID AND LOKASYONID = @NEREYE

    --LAST part which I pull back from the service
    UPDATE STOK_TABLO 
    SET ADET -= @ADET 
    WHERE URUNID = @YeniUrunID AND LOKASYONID = @NEREDEN

    UPDATE STOK_TABLO 
    SET ADET += @ADET 
    WHERE URUNID = @YeniUrunID AND LOKASYONID = @NEREYE

    SELECT * FROM SERVIS_GON_TABLO
END

原存储过程存在的问题

  • 参数不匹配:存储过程定义的参数中无@URUNID、@ID、@ADET、@NEREDEN、@NEREYE,但代码中直接使用这些未声明的参数,会导致执行错误;
  • 逻辑缺失:未获取原维修记录中的产品ID,无法完成“撤销原产品发货”的库存回滚操作;
  • 变量未赋值:@YeniUrunID等声明的变量未被赋值,后续更新逻辑完全无效;
  • 命名不一致:定义的@QTY在代码中用@ADET,@FROM用@NEREDEN,@TO用@NEREYE,参数名混乱。

修正后的存储过程

ALTER PROCEDURE UPDATE_SERVIS_STOK
    @SERVISID INT, -- 要修改的维修记录ID
    @YeniUrunID NVARCHAR(100), -- 新的产品ID(比如COMPUTER)
    @YeniModelID NVARCHAR(100), -- 新产品的型号ID
    @QTY INT, -- 调整数量(这里固定为1)
    @DepoLokasyon NVARCHAR(60), -- 仓库地点ID
    @ServisLokasyon NVARCHAR(60), -- 维修地点ID
    @TEDARIKID NVARCHAR(150), -- 供应商ID
    @TED_TEL NVARCHAR(50) -- 供应商电话
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @EskiUrunID NVARCHAR(100); -- 原产品ID(比如扫码枪)

    -- 开启事务,保证操作原子性
    BEGIN TRANSACTION;
    BEGIN TRY
        -- 1. 获取原维修记录中的产品ID
        SELECT @EskiUrunID = URUNID
        FROM SERVIS_GON_TABLO
        WHERE SERVISID = @SERVISID;

        -- 2. 更新维修发货记录表的产品信息
        UPDATE SERVIS_GON_TABLO
        SET URUNID = @YeniUrunID,
            MODELID = @YeniModelID,
            TEDARIKID = @TEDARIKID,
            TEDARIK_TELEFON = @TED_TEL
        WHERE SERVISID = @SERVISID;

        -- 3. 撤销原产品的库存变动:原产品从维修地点退回仓库
        UPDATE STOK_TABLO
        SET ADET = ADET - @QTY
        WHERE URUNID = @EskiUrunID AND LOKASYONID = @ServisLokasyon;

        UPDATE STOK_TABLO
        SET ADET = ADET + @QTY
        WHERE URUNID = @EskiUrunID AND LOKASYONID = @DepoLokasyon;

        -- 4. 执行新产品的库存变动:新产品从仓库发往维修地点
        UPDATE STOK_TABLO
        SET ADET = ADET - @QTY
        WHERE URUNID = @YeniUrunID AND LOKASYONID = @DepoLokasyon;

        UPDATE STOK_TABLO
        SET ADET = ADET + @QTY
        WHERE URUNID = @YeniUrunID AND LOKASYONID = @ServisLokasyon;

        -- 提交事务
        COMMIT TRANSACTION;

        -- 返回更新后的维修记录
        SELECT * FROM SERVIS_GON_TABLO WHERE SERVISID = @SERVISID;
    END TRY
    BEGIN CATCH
        -- 出错则回滚事务
        ROLLBACK TRANSACTION;
        -- 抛出错误信息
        THROW;
    END CATCH
END

修正说明

  1. 参数规范化:重新定义了清晰的参数名,明确每个参数的用途,添加了必要的@SERVISID和@YeniUrunID;
  2. 事务控制:用TRY/CATCH包裹事务,确保所有库存操作要么全部成功,要么全部回滚,避免数据不一致;
  3. 逻辑补全:先获取原产品ID,完成原产品的库存回滚,再执行新产品的库存变动,完全匹配业务场景;
  4. 错误处理:添加了错误捕获机制,执行出错时会回滚并抛出错误,便于排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 21:30:26