【问题标题】:How can I validate data before insert/update with SQL Server?如何在使用 SQL Server 插入/更新之前验证数据?
【发布时间】:2016-07-30 18:55:44
【问题描述】:

我有一个这样定义的表

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 上的数据?

【问题讨论】:

  • raiserror function 中使用错误严重性或错误编号或编写检查约束而不是触发器

标签: sql sql-server sql-server-2008 triggers ddl


【解决方案1】:

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

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

【讨论】:

  • 非常酷!现在是我用谷歌搜索触发器和约束之间的区别的时候了。如果时间允许,我会接受你的回答。
【解决方案2】:

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

但是,这样做可能更容易:

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

如果您一次插入一行,那么constraint 就是要走的路。

【讨论】:

    【解决方案3】:

    因为 SQL 服务器不知道您根据 ForeignPropertyId 和 ForeignValue 引用的记录。

    1) 你应该使用 MAGIC TABLE。已插入。ForeignPropertyId 为 NULL 并且已插入。ForeignValue 为 NULL。

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

    如果您对触发器不太满意,我的建议是不要过多地使用它们。以后会让你头疼的。

    【讨论】:

      【解决方案4】:

      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
      

      【讨论】:

        【解决方案5】:

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

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

        您可以通过参考下面的 sn-p 来更改现有列。

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

        【讨论】:

          猜你喜欢
          • 2023-03-03
          • 1970-01-01
          • 1970-01-01
          • 2015-08-15
          • 2016-07-12
          • 1970-01-01
          • 2016-10-12
          • 1970-01-01
          • 2011-09-16
          相关资源
          最近更新 更多