Использование функции sql для ограничения CHECK для вновь вставленной строки

Прежде всего мне нужна помощь в этом для моей дипломной работы. Я делаю всю базу данных на SQL Server 2008, выпуск 2. Проблема в проверочном ограничении, использующем функцию, которая работает сама по себе, но не с использованием в ограничении. Результатом ограничения должно быть что-то вроде этого: работник может ездить только в одну деловую поездку в день.

Столовые Деловые поездки:

CREATE TABLE SluzebniCesta(
idSluzCesty int PRIMARY KEY NOT NULL,
DatumCesty DATE NOT NULL,
CasOdjezdu TIME(0) NOT NULL,
CasPrijezdu TIME(0),
CONSTRAINT Odjezd_prijezd CHECK(CasPrijezdu > DATEADD(hour,2,CasOdjezdu))
);

Таблица, которая содержит работников, которые отправляются в командировку:

CREATE TABLE ZamNaCeste(
idZamNaCeste int PRIMARY KEY NOT NULL,
SluzebCestaID int NOT NULL,
ZamestnanecID int NOT NULL,
FOREIGN KEY (ZamestnanecID) REFERENCES Zamestnanec(idZamestnance),
FOREIGN KEY (SluzebCestaID) REFERENCES SluzebniCesta(idSluzCesty)
);

Внешний ключ ZamestnanecID является идентификатором сотрудника, а SluzebCestaID - идентификатором командировки.

Теперь функция:

CREATE FUNCTION myCheckZamNaCeste(@SluzebCestaID int, @ZamestnanecID int)
RETURNS int
AS
BEGIN
    DECLARE @retVal int;
    DECLARE @Zamestnanec int;
    DECLARE @SluzebniCesta int;
    SET @Zamestnanec = (SELECT idZamestnance FROM Zamestnanec WHERE idZamestnance=@ZamestnanecID);
    SET @SluzebniCesta = (SELECT idSluzCesty FROM SluzebniCesta WHERE idSluzCesty=@SluzebCestaID);
    IF EXISTS ( SELECT DatumCesty FROM SluzebniCesta
    WHERE idSluzCesty = @SluzebniCesta
    AND DatumCesty IN (SELECT DatumCesty FROM ZamNaCeste
    LEFT JOIN SluzebniCesta
    ON ZamNaCeste.SluzebCestaID = SluzebniCesta.idSluzCesty
    WHERE ZamestnanecID=@Zamestnanec))
    BEGIN
    SET @retVal=0;
    END
    ELSE
    BEGIN
    SET @retVal=1;
    END
    return @retVal
END
GO

И таблица изменения таблицы, которая содержит данные о сотрудниках и их поездках:

ALTER TABLE ZamNaCeste
ADD CONSTRAINT check_cesty_zamestnance CHECK(dbo.myCheckZamNaCeste(SluzebCestaID,ZamestnanecID)=1);

И когда я пытаюсь ввести любую новую строку, ограничение нарушается, даже если функция выдает правильные данные. возврат 1 - это хороший результат....

2 ответа

Решение

Во-первых, я не уверен, но похоже, что два set операторы в функции собираются извлекать из таблиц те же самые значения, которые они уже имеют, передаваемые в качестве параметров.

Во-вторых, я не вижу ничего ограничивающего поездки в тот же день. В любом месте.

Если вы хотите ограничить поездку сотрудника одной поездкой в ​​день, это легко.

CREATE TABLE ZamNaCeste(
    idZamNaCeste int PRIMARY KEY NOT NULL,
    SluzebCestaID int NOT NULL,
    ZamestnanecID int NOT NULL,
    TripDate      date not null,
    FOREIGN KEY (ZamestnanecID) REFERENCES Zamestnanec(idZamestnance),
    FOREIGN KEY (SluzebCestaID) REFERENCES SluzebniCesta(idSluzCesty),
    constraint UQ_OneTripPerDay unique( ZamestnanecID, TripDate )
);

Уникальное ограничение гарантирует, что один и тот же сотрудник не может зарегистрировать более одной поездки в один и тот же день.

Ну, в конце концов, я решил с более сложным и лучше выглядящим решением. Занятость ограничена временем прибытия и отъезда. И я решил это с помощью функции, которая возвращает количество неправильных вхождений, если его ноль, чем все в порядке, и это работает:

SELECT COUNT(*) FROM(SELECT * FROM SluzebniCesta JOIN ZamNaCeste ON SluzebniCesta.idSluzCesty = ZamNaCeste.SluzebCestaID) AS a JOIN (SELECT * FROM SluzebniCesta2 JOIN ZamNaCeste ON SluzebniCesta.idSluzCesty = ZamNaCeste.SluzebCestaID)AS b ON a.SluzebCestaID b.SluzebCestaID AND a.CasOdjezdu b.CasOdjezdu AND a.ZamestnanecID = b.ZamestnanecID AND (SELECT SluzebniCesta.DatumCesty FROM SluzebniCesta WHERE SluzebniCesta.idSluzCesty = a.SluzebCestaID) = (SELECT SluzebniCesta.DatumCesty FROM SluzebniCesta WHERE SluzebniCesta.idSluzCesty = b.SluzebCestaID)
Другие вопросы по тегам