弹出警报消息时如何停止SQL存储过程中的事务
Posted
技术标签:
【中文标题】弹出警报消息时如何停止SQL存储过程中的事务【英文标题】:How to stop transaction in SQL stored procedure when pop up alert message 【发布时间】: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
.
你必须拆分你的程序。
【参考方案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
【讨论】:
以上是关于弹出警报消息时如何停止SQL存储过程中的事务的主要内容,如果未能解决你的问题,请参考以下文章