如何使用 SQL 服务器在 insert/update 之前验证数据?

How can I validate data before insert/update with SQL Server?

我有一个 table 定义如下

CREATE TABLE [dbo].[ObjectRelationClauses]
(
    [Id] INT NOT NULL PRIMARY KEY IDENTITY, 
    [RelationId] INT NOT NULL, 
    [OperatorType] NVARCHAR(3) NOT NULL, 
    [LocalPropertyId] INT NOT NULL, 
    [ForeignPropertyId] INT NULL, 
    [ForeignValue] VARCHAR(255) NULL, 
    [ParentClauseId] INT NULL
)

如果 ForeignPropertyIdForeignValue 列的值都是 null,我需要能够引发错误,否则我想执行该操作。

这是我试过的

CREATE TRIGGER [dbo].[Trigger_ObjectRelationClauses]
    ON [dbo].[ObjectRelationClauses]
    FOR INSERT, UPDATE
    AS
    BEGIN
        SET NoCount ON
        IF(ForeignPropertyId IS NULL AND ForeignValue IS NULL)
        BEGIN
           RAISERROR('Either ForeignPropertyId or ForeignValue must be provided to perform this action!')
        END

    END

但这给了我一个语法错误。也许,我使用 RAISERROR 的方式是错误的。

如何正确添加触发器来验证 INSERTUPDATE 上的数据?

这看起来像是检查约束的工作,而不是触发器:

ALTER TABLE [dbo].[ObjectRelationClauses]
ADD CONSTRAINT foreign_chk CHECK 
([ForeignPropertyId] IS NOT NULL OR [ForeignValue] IS NOT NULL);

因为 SQL 服务器根据 ForeignPropertyId 和 ForeignValue 不知道您指的是哪条记录。

1) 您应该已经使用了 MAGIC TABLE。 inserted.ForeignPropertyId 为 NULL 且 inserted.ForeignValue 为 NULL。

2) 您可以使用 Instead Of 触发器,而不是 For/After 触发器。

如果您不太习惯使用触发器,我的建议是不要过度使用它们。以后会让你很头疼的。

您可以添加约束。但是,如果要插入多行,则约束将阻止插入 any 行。要解决此问题,您可以使用 instead of 触发器。

但是,简单地做可能更容易:

insert into ObjectRelationClauses(. . .)
    select . . .
    from . . .
    where ForeignPropertyId is not null or ForeignValue is not null;

如果您一次插入一行,那么 constraint 就是正确的选择。

RAISERROR 所需的严重性和状态级别。请使用此查询

CREATE TRIGGER [dbo].[Trigger_ObjectRelationClauses]
ON [dbo].[ObjectRelationClauses]
FOR INSERT, UPDATE
AS
BEGIN
    SET NoCount ON;
    DECLARE @ForeignPropertyId INT ,@ForeignValue varchar(255)
     Select @ForeignPropertyId=  i.ForeignPropertyId, @ForeignValue = i.ForeignValue from Inserted i
    IF(@ForeignPropertyId IS NULL AND @ForeignValue IS NULL)
    BEGIN
       RAISERROR ('Either ForeignPropertyId or ForeignValue must be provided to perform this action!',16,1)
    END

END

为什么不能使用 SQL NOT NULL 约束?

NOT NULL 约束强制列不接受 NULL 值。

您可以参考以下代码段来更改现有列。

ALTER TABLE [Table] ALTER COLUMN [Column] INTEGER NOT NULL;