Sql 抛出错误仍然执行查询并将数据插入表中

Sql 抛出错误仍然执行查询并将数据插入表中,sql,sql-server,throw,raiserror,Sql,Sql Server,Throw,Raiserror,基本上,我尝试比较用户将输入的日期,如果它大于todays date(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 @Erro

基本上,我尝试比较用户将输入的日期,如果它大于todays date(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)
得到这个:

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

(1 row(s) affected)

您正在引发严重性为
severity
=1的错误,这对服务器意味着这只是信息消息请查看对此帖子的回复:
msdn上还有一个指向严重性表的链接。

您的代码在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

我试图将其更改为使用严重性16,尽管它看起来不起作用。ELSE RAISERROR(@ErrorMessage,16,1)。我相信这是正确的语法,但它仍在插入数据。您如何处理异常?你必须检查外面的错误。顺便说一下,触发器不是提交的好地方。您可以先将
ROLLBACK
放在那里,然后将
raiserror
放在那里。因此,在当前的实现中,逻辑有点颠倒,这是有道理的。我们实际上只关注函数和过程中的回滚和提交,但当我将回滚放在其中的任何位置时,我得到了以下信息:Msg 50000,级别16,状态1,过程检查日期,第20行日期必须在2016-02-17 Msg 3609,级别16,状态1,行1之前。事务在触发器中结束。批处理已中止。最好的方法是在插入前检查。为什么不改为出现错误?
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