【问题标题】:How to stop transaction in SQL stored procedure when pop up alert message弹出警报消息时如何停止SQL存储过程中的事务
【发布时间】:2013-12-31 09:37:55
【问题描述】:

基于下面的 C# 代码,我在 SQL 存储过程中编写了 inv_qty == 2 时的语句,以弹出警报消息。

但是在显示警报消息后。数据交易已被记录。如果弹出警报消息处于活动状态,如何停止交易?

据我所知,如果写语句,SQL 存储过程无法停止事务,我该如何实现呢?

 float INV_QTY = Convert.ToInt32(_cmd.Parameters["@RecordFound"].Value.ToString());
                   if (INV_QTY == 2)
                 {
         ScriptManager.RegisterStartupScript(this, this.GetType(), "Message", "alert('" + Item + " Qty is more than exist Qty');window.location.href = 'MMS_Issue.aspx';", true);
                    }
    USE [CIMProRPT01]
     GO
    SET ANSI_NULLS ON
     GO
   SET QUOTED_IDENTIFIER ON
       GO
     ALTER PROCEDURE [dbo].[MMSIssue_InsertOrUpdate] 
     @INV_TRANS_ID VARCHAR(40)
     ,@INV_ID VARCHAR(40)
      ,@INV_LOCATION VARCHAR(40) 
      ,@INV_QTY FLOAT
      ,@INV_TRANS_REQUESTOR VARCHAR(40)
      ,@INV_TRANS_REFNO VARCHAR(40)
      ,@INV_TRANS_REMARK VARCHAR(255)
      ,@INV_REASON_ID VARCHAR(40)
     ,@INV_REASON_REMARK VARCHAR(255)
      ,@INV_CREATE_DATE DATETIME
       ,@INV_CREATE_USER VARCHAR (255)

       ,@INV_FROMLOC VARCHAR (40)
        ,@RecordFound INT OUTPUT
      AS
         BEGIN
      SET NOCOUNT ON;

IF EXISTS(SELECT * FROM OTH_INV_QTY_LOC WHERE INV_ID = @INV_ID and INV_LOCATION = @INV_LOCATION)
BEGIN
    UPDATE OTH_INV_QTY_LOC SET [INV_ID] = @INV_ID,INV_LOCATION = @INV_LOCATION , INV_QTY = INV_QTY - @INV_QTY WHERE INV_ID = @INV_ID AND INV_LOCATION = @INV_LOCATION

    INSERT INTO OTH_INV_TRANSACTION (INV_TRANS_ID,INV_ID,INV_TRANS_LOCATION,INV_TRANS_QTY,INV_TRANS_REQUESTOR,INV_TRANS_REFNO,INV_TRANS_REMARK,INV_REASON_ID,INV_REASON_REMARK,INV_CREATE_DATE,INV_CREATE_USER,INV_FROMLOC)VALUES (@INV_TRANS_ID,@INV_ID,@INV_LOCATION,@INV_QTY,@INV_TRANS_REQUESTOR,@INV_TRANS_REFNO,@INV_TRANS_REMARK,@INV_REASON_ID,@INV_REASON_REMARK,@INV_CREATE_DATE,@INV_CREATE_USER,@INV_FROMLOC)


    DECLARE  @InvFindQTY FLOAT SET @InvFindQTY = ( SELECT INV_QTY FROM OTH_INV_QTY_LOC)

    IF  @InvFindQTY >= @INV_QTY 
    BEGIN
        SELECT @RecordFound = 2
    END
ELSE
    BEGIN
        SELECT @RecordFound = 1
    END
END
      ELSE 
      BEGIN
           SELECT @RecordFound = 0
   END
         END

【问题讨论】:

  • BEGIN TRY/END TRY/BEGIN CATCH/END CATCH.
  • 你必须拆分你的程序。

标签: c# javascript sql sql-server stored-procedures


【解决方案1】:

您不能暂停已启动的事务,您需要将您的过程分成两部分,并在弹出窗口或您喜欢的任何条件后调用第二部分。

如果你想回滚事务,你可以分别使用 BEGIN TRAN 和 COMMIT/ROLLBACK。 .NET Transactions 也可以用于回滚。

【讨论】:

    【解决方案2】:

    你写了when inv_qty == 2,但你的过程返回@RecordFound,根据我对sql的理解,如果@InvFindQTY >= @INV_QTY和proc返回@RecordFound = 2,一切都很好

    • @INV_QTY 被传递给过程
    • 如果给定条件inv_id = @INV_ID AND inv_location = @INV_LOCATION,则表oth_inv_qty_loc的列inv_qty更新inv_qty = inv_qty - @INV_QTY
    • 更新后获取@InvFindQTY = (SELECT inv_qty FROM oth_inv_qty_loc)的值
    • @RecordFound 设置取决于@InvFindQTY >= @INV_QTY

    因此,基本上,您似乎可以将语句包装在事务中并仅在 inv_qty >= @INV_QTY 时更新表,这意味着如果当前库存大于或等于某人想要从库存中取出的金额 @INV_QTY

    【讨论】:

      【解决方案3】:
      ALTER PROCEDURE [dbo].[MMSIssue_InsertOrUpdate]
          @INV_TRANS_ID VARCHAR(40)
          ,@INV_ID VARCHAR(40)
          ,@INV_LOCATION VARCHAR(40) 
          ,@INV_QTY FLOAT
          ,@INV_TRANS_REQUESTOR VARCHAR(40)
          ,@INV_TRANS_REFNO VARCHAR(40)
          ,@INV_TRANS_REMARK VARCHAR(255)
          ,@INV_REASON_ID VARCHAR(40)
          ,@INV_REASON_REMARK VARCHAR(255)
          ,@INV_CREATE_DATE DATETIME
          ,@INV_CREATE_USER VARCHAR (255)
          ,@INV_FROMLOC VARCHAR (40)
          ,@RecordFound INT OUTPUT
      AS
      BEGIN
          SET NOCOUNT ON;
      
          IF EXISTS(SELECT * 
              FROM OTH_INV_QTY_LOC 
              WHERE INV_ID = @INV_ID 
                  AND INV_LOCATION = @INV_LOCATION)
          BEGIN
              BEGIN TRY   
                  -- start the transaction
                  BEGIN TRANSACTION 
      
                  UPDATE OTH_INV_QTY_LOC 
                  SET [INV_ID] = @INV_ID,INV_LOCATION = @INV_LOCATION , INV_QTY = INV_QTY - @INV_QTY 
                  WHERE INV_ID = @INV_ID AND INV_LOCATION = @INV_LOCATION
      
                  -- you can start the transaction from here
                  -- BEGIN TRANSACTION 
      
                  INSERT INTO OTH_INV_TRANSACTION (INV_TRANS_ID,INV_ID,INV_TRANS_LOCATION,INV_TRANS_QTY,INV_TRANS_REQUESTOR,INV_TRANS_REFNO,INV_TRANS_REMARK,INV_REASON_ID,INV_REASON_REMARK,INV_CREATE_DATE,INV_CREATE_USER,INV_FROMLOC)
                  VALUES (@INV_TRANS_ID,@INV_ID,@INV_LOCATION,@INV_QTY,@INV_TRANS_REQUESTOR,@INV_TRANS_REFNO,@INV_TRANS_REMARK,@INV_REASON_ID,@INV_REASON_REMARK,@INV_CREATE_DATE,@INV_CREATE_USER,@INV_FROMLOC)
      
                  DECLARE  @InvFindQTY FLOAT 
                  SET @InvFindQTY = ( SELECT INV_QTY FROM OTH_INV_QTY_LOC)
      
                  IF  @InvFindQTY >= @INV_QTY 
                  BEGIN
                      SELECT @RecordFound = 2;
                      THROW 51000, '@RecordFound = 2', 1; 
                  END
                  ELSE
                  BEGIN
                      SELECT @RecordFound = 1
                  END
              END TRY
              BEGIN CATCH         
                  ROLLBACK TRANSACTION            
              END CATCH
      
              -- Commit the transaction 
              IF XACT_STATE() = 1 COMMIT TRANSACTION 
              -- For safety
              ELSE IF XACT_STATE() = -1 ROLLBACK TRANSACTION 
          END
          ELSE 
          BEGIN
              SELECT @RecordFound = 0
          END
      END
      

      【讨论】:

        猜你喜欢
        • 2012-08-22
        • 1970-01-01
        • 1970-01-01
        • 2014-11-23
        • 1970-01-01
        • 2017-02-13
        • 2021-04-17
        • 2018-10-03
        • 1970-01-01
        相关资源
        最近更新 更多