The issue is not in function CheckStateFinished but with existing data in table Participation on which CHECK CONSTRAINT is to be added. When we add Check constraint to an existing table using Alter table command by default it applies to both existing data and any new data. There might be some row in table Participation where for given StudentID, CourseID, CoursePeriod, SchoolYear, _State parameters function is evaluating to 0 and hence Check constraint is getting failed.
In such a case use WITH NOCHECK option so that Check constraint applies only to new data.
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