使SQL Server仅在插入或更新的行上使用CHECK CONSTRAINT

Dav*_*eer 2 sql-server stored-procedures check-constraints

我想将业务规则应用于表中的行(SQL Server 2008).但是,表中的历史数据不符合此规则,并且没有好的方法使其符合(没有合理默认值的未知值.)所以我希望在新插入时检查CHECK CONSTRAINT 行,或更新行时.

我创建了这样一个约束,并设置以下值:

  • 在创建或重新启用时检查现有数据:否
  • 强制执行INSERT和UPDATE:是的
  • 强制复制:是的

插入新记录时,一切似乎都很好.但是,如果我更新记录,即使更新的记录符合CHECK CONSTRAINT,CHECK CONSTRAINT也会失败.就好像它正在尝试在更新单行时将约束应用于所有行.我怎么能阻止这个?

这是约束:

([DateGiven] IS NULL 
 AND [PrimaryConsultantId] IS NULL 
 AND [AdditionalConsultants] IS NULL 
 AND [ResultingClaLevel] IS NULL)
OR ([DateGiven] IS NOT NULL 
 AND [PrimaryConsultantId] IS NOT NULL 
 AND [AdditionalConsultants] IS NOT NULL 
 AND [ResultingClaLevel] IS NOT NULL))
Run Code Online (Sandbox Code Playgroud)

更新是通过存储过程完成的:(ClaEvaluationId是主键)

CREATE PROCEDURE [dbo].[UpdateProc] (
    @ClaEvaluationId int,
    @DateScheduled datetime,
    @DateGiven datetime,
    @PrimaryConsultantId int,
    @AdditionalConsultants nvarchar(500),
    @ResultingClaLevel decimal(2,1)
) AS

SET NOCOUNT ON

UPDATE [dbo].[ClaEvaluation]
SET
    [DateScheduled] = @DateScheduled
    ,[DateGiven] = @DateGiven
    ,[PrimaryConsultantId] = PrimaryConsultantId
    ,[AdditionalConsultants] = @AdditionalConsultants
    ,[ResultingClaLevel] = @ResultingClaLevel
WHERE [ClaEvaluationId] = @ClaEvaluationId
Run Code Online (Sandbox Code Playgroud)

A-K*_*A-K 5

您的过程中的以下行是错误的:

,[PrimaryConsultantId] = PrimaryConsultantId
Run Code Online (Sandbox Code Playgroud)

应该

,[PrimaryConsultantId] = @PrimaryConsultantId
Run Code Online (Sandbox Code Playgroud)

您的约束正在按预期工作,并为您暴露了一个错误.