我在一个表上有一个Check约束,该表调用一个函数来评估一个条件。当我直接调用函数时,对于虚拟值,它确实返回true。
当我运行一个insert语句时,check constraint返回false,表示我在直接调用函数时使用的相同值。
为了进一步检查,我想将check约束(在insert语句中)发送的数据记录到SQL函数中。
在这种情况下SQL Profiler会帮助我吗?
这是功能代码(T-SQL)
CREATE FUNCTION [dbo].[fn_CheckLeaveContinuation] (@emp_Id INT,
@leaveDate DATETIME,
@severityPoint INT)
RETURNS BIT
AS
BEGIN
--For the given emp_id and the leave date, check if the given employee
-- has already taken a leave on the previous day. Leaves in continuation
-- should have severity point as Zero else return false
DECLARE @isLeaveContinued BIT;
--if it's a first leave of the employee then return true
SELECT @isLeaveContinued=
CASE
WHEN NOT EXISTS (SELECT *
FROM absenteeism
WHERE EMP_ID = @emp_ID)
OR EXISTS (SELECT *
FROM absenteeism
WHERE DateDiff(DAY, @leaveDate, Absent_Date) = -1
AND EMP_ID = @emp_ID)
AND @severityPoint = 0
OR EXISTS (SELECT *
FROM Absenteeism
WHERE DateDiff(DAY, @leaveDate, Absent_Date) < -1
)
THEN
'true'
ELSE 'false'
END
RETURN @isLeaveContinued
END
表格结构
CREATE TABLE [dbo].[Absenteeism](
[EMP_ID] [int] NOT NULL,
[Absent_date] [datetime] NOT NULL,
[Reason_code] [char](40) NOT NULL,
[Severity_Points] [int] NOT NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Absenteeism] WITH CHECK ADD CONSTRAINT [chk_Leave_Continuation] CHECK (([dbo].[fn_CheckLeaveContinuation]([Emp_ID],[Absent_date],[Severity_Points])='true'))
GO
ALTER TABLE [dbo].[Absenteeism] CHECK CONSTRAINT [chk_Leave_Continuation]
GO
ALTER TABLE [dbo].[Absenteeism] WITH CHECK ADD CHECK (([severity_points]>=(0) AND [severity_points]<=(4)))
答案 0 :(得分:1)
问题是在插入记录后评估检查约束,这会因为它是自引用而改变函数的返回值。它的设置方式,如果你有一个空表,就不可能在表中插入任何记录。
这是因为一旦插入记录
NOT EXISTS (SELECT * FROM absenteeism WHERE EMP_ID = @emp_ID)
永远不会成真。首次插入特定员工时
EXISTS (
SELECT *
FROM absenteeism2
WHERE DateDiff(DAY, @leaveDate, Absent_Date) = -1
AND EMP_ID = @emp_ID)
永远不会是真的,因为该员工没有其他记录。最后
EXISTS (
SELECT *
FROM Absenteeism2
WHERE DateDiff(DAY, @leaveDate, Absent_Date) < -1
)
只有在表格中已经缺席前几天才能成立。如果您不能为员工插入多条记录,因为前两个条件不能成立,则第三个条件永远不会启动。
也许你想从第一个条件中排除(刚刚插入的)缺席日
NOT EXISTS (
SELECT *
FROM absenteeism
WHERE EMP_ID = @emp_ID
AND Absent_Date <> @leaveDate)