【问题标题】:THROW ERROR Still Executes Query And Inserts Data Into TableTHROW ERROR 仍然执行查询并将数据插入表中
【发布时间】:2016-05-30 03:52:24
【问题描述】:

基本上,我试图比较用户将输入的日期,如果它大于今天的日期 (GETDATE()),那么它会抛出错误并且不输入数据。查询抛出错误,但它仍然输入数据,结果在底部。

USE EMR
GO

IF EXISTS (SELECT DB_ID('CheckDate'))
    DROP TRIGGER CheckDate
    GO

CREATE TRIGGER CheckDate
ON VISIT
AFTER INSERT, UPDATE
AS
BEGIN TRAN
    DECLARE @ErrorMessage VARCHAR(200)
    DECLARE @Date VARCHAR(20) = CAST ((SELECT CONVERT (DATE, GETDATE())) AS VARCHAR(20))
    SET @ErrorMessage = 'Date Must Be On Or Before ' + @Date + '';

    DECLARE @CheckDate DATE = (SELECT Date_Of_Service FROM inserted);

    IF CAST((@CheckDate) AS DATE) <= CAST(GETDATE() AS DATE)
        COMMIT TRAN

    ELSE
        RAISERROR(@ErrorMessage, 1, 1)

这是我的插入语句:

INSERT INTO VISIT (PK_VISIT_ID, Date_Of_Service)
VALUES (02913, '2018-12-03')

得到这个:

Date Must Be On Or Before 2016-02-17
Msg 50000, Level 1, State 1

(1 row(s) affected)

【问题讨论】:

  • 为什么不给THROW一个错误呢?

标签: sql sql-server throw raiserror


【解决方案1】:

您使用severity = 1 引发错误,这意味着服务器只是信息消息

查看对此帖子的回复:TSQL: Prevent trigger suppressing error but rolling back transaction
msdn 上还有一个严重性表的链接。

【讨论】:

  • 我尝试将其更改为使用严重性 16,尽管它看起来不像它的工作。
  • ELSE RAISERROR(@ErrorMessage, 16, 1)。我相信这是正确的语法,但它仍在插入数据
  • 你是如何处理异常的?您必须检查外部错误。顺便说一句,触发器对于COMMIT 来说不是好地方。你可以先放ROLLBACK,然后放raiserror。所以在当前的实现中逻辑有点颠倒。
  • 这是有道理的。我们真的只专注于在函数和过程中执行 ROLLBACK 和 COMMIT,但是当我将回滚放在那里的任何地方时,我得到这个:Msg 50000, Level 16, State 1, Procedure CheckDate, Line 20 Date Must Be On or Before 2016- 02-17 Msg 3609, Level 16, State 1, Line 1 事务在触发器中结束。该批次已中止。
  • 最好的方法是在插入之前进行检查。
【解决方案2】:

即使在 raiserror 之后,您的代码也会执行插入操作,因为 insert 触发器会在插入行之后运行触发器。您可以使用检查约束或代替 insert,如下所示:

alter trigger tr2 on bb
instead of insert
as
begin
    begin try
        begin transaction
            if exists(select * from inserted where date1  > getdate())
                    begin
                        raiserror('date greater then today''s date',16,1)
                    end

                else
                    begin
                        insert into bb
                        select * from inserted
                        if @@trancount > 0
                        commit transaction
                    end
    end try

    begin catch
        declare @msg varchar(100) = error_message()
            if @@trancount > 0
                begin
                    raiserror(@msg,16,1)
                    rollback transaction
                end         
    end catch
end

【讨论】:

    猜你喜欢
    • 2022-10-08
    • 1970-01-01
    • 2017-01-29
    • 2013-04-15
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    相关资源
    最近更新 更多