当我尝试向其中一个表添加约束时出现问题。我想检查一个函数,以便状态为真,然后返回1或0,具体取决于它是否为真。但是在函数中我检查列中的值是否为NULL并导致错误
ALTER TABLE语句与CHECK约束“chk_StateFinished”冲突。冲突发生在数据库“databaseName”,表“dbo.Participation”。
函数看起来像这样
CREATE FUNCTION CheckStateFinished(@StudentID varchar(10), @CourseID varchar(10), @CoursePeriod varchar(10),
@SchoolYear int, @State varchar(15)) RETURNS int
AS BEGIN
DECLARE @Grade varchar(1)
SELECT @Grade = Grade FROM Participation WHERE StudentID = @StudentID AND CourseID = @CourseID AND CoursePeriod = @CoursePeriod AND SchoolYear = @SchoolYear
RETURN CASE WHEN @State = 'Avslutad' AND @Grade = 'U' OR @Grade IS NULL THEN 0
ELSE 1
END
END
Add Check Constraint如下所示:
ALTER TABLE Participation ADD CONSTRAINT chk_StateFinished CHECK (dbo.CheckStateFinished(StudentID, CourseID, CoursePeriod, SchoolYear, _State) = 1)
我应该怎么做而不是函数中的IS NULL,或者我应该做些什么呢?
答案 0 :(得分:3)
问题不在CheckStateFinished函数中,而是在表中的现有数据中要添加CHECK CONSTRAINT的参与。当我们使用Alter table命令将Check约束添加到现有表时,它默认适用于现有数据和任何新数据。 表格中可能有某些行参与其中给定的StudentID,CourseID,CoursePeriod,SchoolYear,_State参数函数评估为0,因此检查约束失败。
在这种情况下,使用WITH NOCHECK选项,以便Check约束仅适用于新数据。
create table Participation (Grade varchar(1),StudentID varchar(10), CourseID varchar(10), CoursePeriod varchar(10), SchoolYear int, [State] varchar(15))
insert into Participation values ('A','Student1','Course1','CourseP1',2013,'Avslutad')
-- for this row check constraint will work fine.
insert into Participation values ('U','Student2','Course1','CourseP1',2013,'Avslutad') -- for this row check constraint will fail.
insert into Participation values (NULL,'Student3','Course1','CourseP1',2013,'Avslutad')
-- for this row check constraint will fail.
insert into Participation values ('U','Student4','Course1','CourseP1',2013,'XYZ')
-- for this row check constraint will work fine.
--insert into Participation values ('A','Student5','Course1','CourseP1',2013,'XYZ')
Go
CREATE FUNCTION CheckStateFinished(@StudentID varchar(10), @CourseID varchar(10), @CoursePeriod varchar(10),
@SchoolYear int, @State varchar(15)) RETURNS int
AS BEGIN
DECLARE @Grade varchar(1)
SELECT @Grade = Grade FROM Participation WHERE StudentID = @StudentID AND CourseID = @CourseID AND CoursePeriod = @CoursePeriod AND SchoolYear = @SchoolYear
RETURN CASE WHEN @State = 'Avslutad' AND @Grade = 'U' OR @Grade IS NULL THEN 0
ELSE 1
END
END
Go
ALTER TABLE Participation WITH NOCHECK -- add this and your constraint will work.
ADD CONSTRAINT chk_StateFinished CHECK (dbo.CheckStateFinished('Student3','Course1','CourseP1',2013,'Avslutad') = 1)
Go