1

我在一个表上有一个 Check 约束,它调用一个函数来评估一个条件。当我直接调用一个函数时,它确实为我返回了虚拟值。

当我运行插入语句时,检查约束对我在直接调用函数时使用的相同值返回 false。

为了进一步检查,我想将检查约束(在插入语句上)发送的数据记录到 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)))
4

1 回答 1

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)
于 2011-12-06T23:53:26.513 回答