powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Проверка пересечения диапазонов в триггере
10 сообщений из 10, страница 1 из 1
Проверка пересечения диапазонов в триггере
    #32033785
PavelK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть таблица из 4-х столбцов: номер объекта, номер атрибута объекта, дата начала и дата окончания.
Диапазоны дат для каждого атрибута любого объекта не должны пересекаться.
Как это проверить в триггере? Перепробовал кучу вариантов,в Query Analyzer все работает, как запихиваю
в триггер нет.
...
Рейтинг: 0 / 0
Проверка пересечения диапазонов в триггере
    #32033793
Фотография jimmers
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Простите, Вы бы код своего триггера привели...
...
Рейтинг: 0 / 0
Проверка пересечения диапазонов в триггере
    #32033818
PavelK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
CREATE TRIGGER tIU_DateAttr ON OrgAttr
FOR INSERT, UPDATE
AS

DECLARE @RetCode int

SET @RetCode = 64001

DECLARE @RetNum int
DECLARE @RetAttr int
DECLARE @RetBDate smalldatetime

SELECT @RetNum = OA.NumOrg, @RetAttr = OA.NumTypeAttr, @RetBDate = OA.BDate
FROM OrgAttr as OA, inserted
WHERE OA.NumOrg = inserted.NumOrg AND OA.NumTypeAttr = inserted.NumTypeAttr AND
((inserted.BDate BETWEEN OA.BDate AND ISNULL(OA.EDate,'1/1/2079') OR ISNULL(inserted.EDate,'1/1/2079') BETWEEN OA.BDate AND ISNULL(OA.EDate,'1/1/2079'))
OR (inserted.BDate < OA.BDate AND ISNULL(inserted.EDate,'1/1/2079') > OA.BDate))
GROUP BY OA.NumOrg,OA.NumTypeAttr,OA.BDate
HAVING COUNT(OA.NumOrg) > 1

IF @@ROWCOUNT > 1
BEGIN
ROLLBACK TRANSACTION
RAISERROR @RetCode 'Диапазоны дат одного атрибута не могут пересекатся!'
END
...
Рейтинг: 0 / 0
Проверка пересечения диапазонов в триггере
    #32033852
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не знаю, я бы так написал:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
CREATE TRIGGER tIU_DateAttr ON OrgAttr 
FOR INSERT, UPDATE 
AS 

DECLARE @RetCode int 

SET @RetCode =  64001  

if exists(
SELECT *
FROM OrgAttr as OA, inserted 
WHERE OA.NumOrg = inserted.NumOrg AND OA.NumTypeAttr = inserted.NumTypeAttr AND 
((inserted.BDate BETWEEN OA.BDate AND ISNULL(OA.EDate,'1/1/2079') OR ISNULL(inserted.EDate,'1/1/2079') BETWEEN OA.BDate AND ISNULL(OA.EDate,'1/1/2079')) 
OR (inserted.BDate < OA.BDate AND ISNULL(inserted.EDate,'1/1/2079') > OA.BDate)) 
GROUP BY OA.NumOrg,OA.NumTypeAttr,OA.BDate 
HAVING COUNT(OA.NumOrg) >  1  
)
  BEGIN 
    ROLLBACK TRANSACTION 
    RAISERROR @RetCode 'Диапазоны дат одного атрибута не могут пересекатся!' 
  END
...
Рейтинг: 0 / 0
Проверка пересечения диапазонов в триггере
    #32033858
PavelK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробовал, не работает!
...
Рейтинг: 0 / 0
Проверка пересечения диапазонов в триггере
    #32033914
Dominic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуйте этот тригер. У меня все вроде работает. Прошу прощение за форматирование - я прямо из Query Analizer`а, а там с табуляторами...

CREATE TRIGGER OrgAttr_INSERT
ON OrgAttr
FOR INSERT, UPDATE
AS

/*
Что такое пересечение диапазонов:
1) INSERTED.BDate <= OrgAtt.BDate AND INSERTED.EDate > OrgAtt.BDate
2) INSERTED.BDate >= OrgAtt.BDate AND INSERTED.BDate < OrgAtt.EDate
3) INSERTED.EDate > OrgAtt.BDate AND INSERTED.EDate <= OrgAtt.EDate
*/
DECLARE @RetCode int

SET @RetCode = 64001

IF EXISTS (
SELECT *
FROM inserted INS
WHERE EXISTS ( SELECT *
FROM OrgAttr OA
WHERE
NOT (OA.NumOrg = INS.NumOrg AND OA.NumTypeAttr = INS.NumTypeAttr) AND
(
(INS.BDate <= OA.BDate AND INS.EDate > OA.BDate) OR
(INS.BDate >= OA.BDate AND INS.BDate < OA.EDate) OR
(INS.EDate > OA.BDate AND INS.EDate <= OA.EDate)
)
)
)
BEGIN ROLLBACK TRANSACTION
RAISERROR @RetCode 'Диапазоны дат одного атрибута не могут пересекатся!'
END

RETURN

Проверку проводил так:
1) Создал целевую таблицу OrgAttr
2) Создал вышеприведенный тригер
3) вставил две записи:

INSERT INTO OrgAttr
VALUES (1,1, '06-06-2002', '06-09-2002')
INSERT INTO OrgAttr
VALUES (1,2, '06-12-2002', '06-18-2002')

4) Попытался вставить запись, нарушающее условие 1:

INSERT INTO OrgAttr
VALUES (2,1, '06-05-2002', '06-09-2002')

5) ... нарушающее условие 2

INSERT INTO OrgAttr
VALUES (2,1, '06-07-2002', '06-09-2002')

6) ... нарушающее условие 3

INSERT INTO OrgAttr
VALUES (2,1, '06-05-2002', '06-20-2002')
...
Рейтинг: 0 / 0
Проверка пересечения диапазонов в триггере
    #32033922
Gregory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IMHO так немного проще . Проверил - работает
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Create TRIGGER OrgAttr_INSERT 
ON OrgAttr 
FOR INSERT, UPDATE 
AS 

 /* 
Что такое пересечение диапазонов - попадание начала одного из диапазонов в другой
 
*/  
DECLARE @RetCode int 

SET @RetCode =  64001  

IF EXISTS ( SELECT * 	FROM inserted INS ,OrgAttr OA WHERE  OA.NumOrg = INS.NumOrg AND OA.NumTypeAttr = INS.NumTypeAttr AND 
(INS.BDate BETWEEN OA.BDate AND ISNULL(OA.EDate,'1/1/2079')  OR OA.BDate BETWEEN INS.BDate AND ISNULL(INS.EDate,'1/1/2079')))
BEGIN ROLLBACK TRANSACTION 
RAISERROR @RetCode 'Диапазоны дат одного атрибута не могут пересекатся!' 
END 

RETURN 
...
Рейтинг: 0 / 0
Проверка пересечения диапазонов в триггере
    #32033927
Dominic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для Gregory:

С уточнением к Вашему примеру - "Если один диапазон полностью внутри другого - то это нормальная ситуация" .
Тогда все работает.

С уважением, Dominic
...
Рейтинг: 0 / 0
Проверка пересечения диапазонов в триггере
    #32033930
Dominic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для Gregory и всех:

Пошутил, надо уточнить постановку задачи (см. авторский первый постинг):

"Диапазоны дат для каждого атрибута любого объекта не должны пересекаться".

Для меня это означает, что при проверке диапазонов в качестве первичного ключа используется само понятие диапазона без возможности пересечения границ у всех записей .

Обратите внимание на любовно подставленный в моем примере NOT при сравнении ключевых полей в WHERE подзапроса. Для тех, кто забыл: к моменту, когда "trigger fired", вставляемая запись уже находится в целевой таблице, и она противоречит условию сравнения диапазонов. Поэтому она и исключена этим NOT.

Да, поправка к моему примеру. Конечно же надо использовать ISNULL для дат, если поля допускают хранение NULL.
...
Рейтинг: 0 / 0
Проверка пересечения диапазонов в триггере
    #32034123
Фотография AndreK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть у меня похожая задачка.
Я проверял datediff(ss,конц_пред_диапазона_дат,нач_след_диапазона_дат)
ежель это отрицательно - пересекаются и наоборот, заодно и на isnull() проверить можно.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Проверка пересечения диапазонов в триггере
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]