Log function Parameters in Sql Server
-
28-10-2019 - |
Question
I have a Check constraint on a table which calls a function to evaluate a condition. When I directly calls a functions, it does return me true for the dummy values.
When I run an insert statement , check constraint returns me false for same values which I used in directly calling a function .
To check it further, I want to LOG the data sent by check constraint (on insert statement) to the SQL function.
Will SQL Profiler help me in this case ?
Here is the function code (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
Table Structure
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)))
Solution
The problem is the check constraint is evaluated after the record has been inserted, which alters the return value of the function due to it being self referential. The way it is set up, if you have an empty table, it is impossible to insert any records in the table.
This is because once a record is inserted
NOT EXISTS (SELECT * FROM absenteeism WHERE EMP_ID = @emp_ID)
will never be true. And when first inserting for a particular employee
EXISTS (
SELECT *
FROM absenteeism2
WHERE DateDiff(DAY, @leaveDate, Absent_Date) = -1
AND EMP_ID = @emp_ID)
can never be true as there is no other record for that employee. Finally
EXISTS (
SELECT *
FROM Absenteeism2
WHERE DateDiff(DAY, @leaveDate, Absent_Date) < -1
)
can only be true if there are already absent days prior in the table. If you can't insert more than one record for an employee because the first two conditions can't be true, the third condition can never kick in.
Perhaps you want to exclude the (just inserted) absent day from the first condition
NOT EXISTS (
SELECT *
FROM absenteeism
WHERE EMP_ID = @emp_ID
AND Absent_Date <> @leaveDate)