2011-12-06 9 views
1

条件を評価する関数を呼び出すテーブルに対してCheck制約があります。私が直接関数を呼び出すと、ダミー値に対して真を返します。ログ関数Sql Serverのパラメータ

私はinsert文を実行すると、check constraintは私が関数を直接呼び出す際に使用したのと同じ値を返します。

さらにチェックするには、CHECK制約(挿入文の場合)によって送信されたデータをSQL関数に記録します。

この場合、SQLプロファイラは役に立ちますか?ここ

は機能コード(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

コードを表示してください! –

+0

@ClintGood:私は関数とソースコードを追加しました –

答えて

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 
) 

は、表の前に既に欠席日がある場合にのみ真となります。最初の2つの条件が真ではないため、従業員に複数のレコードを挿入できない場合は、3番目の条件は実行されません。

おそらく(欠落した)欠席日を最初の条件

NOT EXISTS (
    SELECT * 
    FROM absenteeism 
    WHERE EMP_ID = @emp_ID 
    AND Absent_Date <> @leaveDate) 
+0

それはどうですか?Check Constraintは最初に行を挿入し、条件を評価し、条件が偽であればロールバックしますか? –

+0

ありがとうクリント!それは動作します。 –