60

我刚刚创建了一个相反的触发器,其语法如下:

Create trigger tgrInsteadTrigger on copytableto
Instead of Insert as 
    Declare @store_name varchar(30);
    declare @sales int;
    declare @date datetime;

    select @store_name = i.store_name from inserted i
    select @sales = i.sales from inserted i
    select @date = i.Date from inserted i
begin
    if (@sales > 1000)
        begin
        RAISERROR('Cannot Insert where salary > 1000',16,1); ROLLBACK;
        end
    else
        begin
        insert into copytablefrom(store_name, sales, date) values (@store_name, @sales, @date);
        Print 'Instead After Trigger Executed';
        end
End

在上面我使用过的语法中RAISERROR('Cannot Insert where salary > 1000',16,1)

但是当我写RAISERROR('Cannot Insert where salary > 1000')它时,它在同一行给出了错误“')'附近的语法错误”。

谁能在这里解释一下 (16,1) 的用法。

4

5 回答 5

74

它是 的严重性级别error。级别从 11 到 20 会引发错误SQL。级别越高,级别越严重,transaction应该中止。

执行此操作时会出现语法错误:

RAISERROR('Cannot Insert where salary > 1000').

因为您没有指定正确的parametersseverity levelstate)。

如果您希望发出警告而不是exception,请使用级别 0 - 10。

来自 MSDN:

严重性

是与此消息关联的用户定义的严重性级别。使用 msg_id 引发使用 sp_addmessage 创建的用户定义消息时,在 RAISERROR 上指定的严重性将覆盖在 sp_addmessage 中指定的严重性。任何用户都可以指定从 0 到 18 的严重级别。从 19 到 25 的严重级别只能由 sysadmin 固定服务器角色的成员或具有 ALTER TRACE 权限的用户指定。对于从 19 到 25 的严重级别,需要 WITH LOG 选项。

状态

是从 0 到 255 的整数。负值或大于 255 的值会生成错误。如果在多个位置引发相同的用户定义错误,则为每个位置使用唯一的状态编号可以帮助找出引发错误的代码部分。在此处进行详细说明

于 2013-04-23T13:04:59.250 回答
38

16 是严重性,1 是状态,更具体地说,以下示例可能会为您提供有关语法和用法的更多详细信息:

BEGIN TRY
    -- RAISERROR with severity 11-19 will cause execution to 
    -- jump to the CATCH block.
    RAISERROR ('Error raised in TRY block.', -- Message text.
               16, -- Severity.
               1 -- State.
               );
END TRY
BEGIN CATCH
    DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

    SELECT 
        @ErrorMessage = ERROR_MESSAGE(),
        @ErrorSeverity = ERROR_SEVERITY(),
        @ErrorState = ERROR_STATE();

    -- Use RAISERROR inside the CATCH block to return error
    -- information about the original error that caused
    -- execution to jump to the CATCH block.
    RAISERROR (@ErrorMessage, -- Message text.
               @ErrorSeverity, -- Severity.
               @ErrorState -- State.
               );
END CATCH;

您可以从http://msdn.microsoft.com/en-us/library/ms178592.aspx关注并尝试更多示例

于 2013-04-23T13:07:28.660 回答
13

根据MSDN

RAISERROR ( { msg_id | msg_str | @local_variable }
    { ,severity ,state }
    [ ,argument [ ,...n ] ] )
    [ WITH option [ ,...n ] ]

16将是严重性。
1将是国家。

您得到的错误是因为您没有正确提供RAISEERROR函数所需的参数。

于 2013-04-23T13:06:19.573 回答
7

示例代码中的严重级别 16 通常用于用户定义(用户检测到的)错误。SQL Server DBMS 本身会针对它检测到的问题发出严重级别(和错误消息),无论是更严重(数字较高)还是不太严重(数字较低)。

状态应该是 0 到 255 之间的整数(负值会出错),但选择基本上是程序员的。如果用户定义错误的相同错误消息将在不同位置出现,则放置不同的状态值很有用,例如,如果通过额外指示错误发生的位置来帮助调试/故障排除问题。

于 2013-04-23T13:15:39.383 回答
4

作为从Microsoft 的 MSDN中获取的示例,发布到这个问题的答案很好,但是如果它不是来自 TRY 块,它并不能直接说明错误的来源。我更喜欢这个示例,它对 CATCH 块中的 RAISERROR 消息进行了非常小的更新,说明错误来自 CATCH 块。我也在 gif 中演示了这一点。

BEGIN TRY
    /* RAISERROR with severity 11-19 will cause execution
     |  to jump to the CATCH block.
    */
    RAISERROR ('Error raised in TRY block.', -- Message text.
               5, -- Severity. /* Severity Levels Less Than 11 do not jump to the CATCH block */
               1 -- State.
               );
END TRY

BEGIN CATCH
    DECLARE @ErrorMessage  NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState    INT;

    SELECT 
        @ErrorMessage  = ERROR_MESSAGE(),
        @ErrorSeverity = ERROR_SEVERITY(),
        @ErrorState    = ERROR_STATE();

    /* Use RAISERROR inside the CATCH block to return error
     | information about the original error that caused
     | execution to jump to the CATCH block
    */
    RAISERROR ('Caught Error in Catch', --@ErrorMessage, /* Message text */
               @ErrorSeverity,                           /* Severity     */
               @ErrorState                               /* State        */
               );
END CATCH;

RAISERROR 演示 Gif

于 2020-06-01T20:40:16.937 回答