Проверьте ограничение, не позволяющее мне добавлять данные - PullRequest
3 голосов
/ 23 октября 2019

У меня есть пользовательская функция, которая возвращает бит.

  • 1 - если даты перекрываются
  • 0 - если даты не перекрываются

Я проверил UDF, и он выглядит какбудет работать правильно.

Это следующее проверочное ограничение, которое я добавил:

ALTER TABLE [Gizmo] WITH CHECK ADD CONSTRAINT [CK_DateOverlap]
CHECK [dbo].[MyUserFunction]([GizmoName],[GizmoState],[BeginDate],[EndDate]) = 0;

В таблице нет данных. Когда я иду, чтобы вставить новую запись, я получаю сообщение об ошибке

The INSERT statement conflicted with the CHECK constraint

Я вручную вызвал UDF для проверки, и он возвращает 0.

Я хочу, чтобы ограничение добавляло записи, еслиUDF возвращает 0. Если он возвращает 1, я не хочу его добавлять.

Что мне не хватает?

РЕДАКТИРОВАТЬ - UDF

ALTER FUNCTION [dbo].[MyUserFunction]
(
     @GizmoName AS VARCHAR(max),
     @GizmoState AS VARCHAR(max),
     @BeginDate AS DATETIME,
     @EndDate AS DATETIME

)

RETURNS BIT
AS
BEGIN
       DECLARE @Result BIT
       IF EXISTS(
                    SELECT *
                    FROM Gizmos
                    WHERE (@GizmoName = Name AND @GizmoState = [State])
                    AND (@EndDate >= EffectiveFrom AND EffectiveTo >= @BeginDate)
                    )
                    BEGIN
                        SET @Result = 1;
                    END
                    ELSE
                    BEGIN
                           SET @Result = 0;   
                    END
       RETURN @Result
END

INSERT

INSERT INTO Gizmos VALUES('XXX', 'CA', '1/1/2019', '12/31/2019');

1 Ответ

1 голос
/ 24 октября 2019

Строка была вставлена ​​в таблицу, и к таблице применено ограничение. Таким образом, данные уже доступны, функции возвращают 1 и транзакция откатывается. поэтому нам нужно игнорировать первый ряд, тогда он работает, как вы ожидали.

CREATE OR ALTER FUNCTION [dbo].[MyUserFunction]
(
     @GizmoName AS VARCHAR(max),
     @GizmoState AS VARCHAR(max),
     @BeginDate AS DATETIME,
     @EndDate AS DATETIME

)

RETURNS BIT
AS
BEGIN
       DECLARE @Result BIT

       IF (SELECT COUNT(Name)
                    FROM Gizmos
                    WHERE (@GizmoName = Name AND @GizmoState = [State])
                    AND (@EndDate >= EffectiveFrom AND EffectiveTo >= @BeginDate)
                    ) > 1
                    BEGIN
                        SET @Result = 1;
                    END
                    ELSE
                    BEGIN
                           SET @Result = 0;   
                    END

                    RETURN @Result

END
GO
...