Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как наложить constraint на таблицу с интервалами?  [new]
OldWoker
Member

Откуда: из далёка
Сообщений: 437
Привет всем! Как наложить проверочное ограничение на таблицу типа

CREATE TABLE Table1
(
	key int NOT NULL Primari Key,
	DateStart datetime NOT NULL,
	DateEnd datetime NOT NULL
)

ограничение - что бы для любого дня @date (DateTime) существовало не более одной записи

select count(*) from Table1
where exists ( select 1 from Table1 where DateStart <=@date and @date<=DateEnd)
18 дек 09, 11:26    [8085340]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
OldWoker
Member

Откуда: из далёка
Сообщений: 437
Create Constraint !!!
18 дек 09, 11:27    [8085354]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
Glory
Member

Откуда:
Сообщений: 104760
CREATE TABLE Table1
(
	key int NOT NULL Primari Key,
	DateStart datetime NOT NULL UNIQUE,
	DateEnd datetime NOT NULL
)
18 дек 09, 11:32    [8085405]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
Le Peace
Member

Откуда: Москва
Сообщений: 8969
Триггер
18 дек 09, 11:37    [8085461]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
UDF+CHECK CONSTRAINT
18 дек 09, 11:42    [8085503]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
OldWoker
Member

Откуда: из далёка
Сообщений: 437
Glory
CREATE TABLE Table1
(
	key int NOT NULL Primari Key,
	DateStart datetime NOT NULL UNIQUE,
	DateEnd datetime NOT NULL
)

Этого маловато!
Извините пропустил строчку

CREATE TABLE Table1
(
	Id int NOT NULL Primari Key,
           Key int not null, -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
	DateStart datetime NOT NULL,
	DateEnd datetime NOT NULL
)

Ограничение что для данного key на любой день только одна запись!
18 дек 09, 11:46    [8085553]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
Glory
Member

Откуда:
Сообщений: 104760
OldWoker


Ограничение что для данного key на любой день только одна запись!

А что за мера такая "один день" ? Не должно быть пересекающихся периодов что ли ?
18 дек 09, 11:49    [8085578]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
OldWoker
Member

Откуда: из далёка
Сообщений: 437
Glory
OldWoker


Ограничение что для данного key на любой день только одна запись!

А что за мера такая "один день" ? Не должно быть пересекающихся периодов что ли ?

Да для данного значения key не должно быть пересекающихся периодов
18 дек 09, 11:52    [8085618]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
aleks2
Guest
https://www.sql.ru/forum/actualthread.aspx?tid=713546

только не нада писать триггеров.
18 дек 09, 12:00    [8085696]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
OldWoker
Member

Откуда: из далёка
Сообщений: 437
aleks2
https://www.sql.ru/forum/actualthread.aspx?tid=713546

только не нада писать триггеров.

Да! Спасибо, то что нужно. Хотя в этих задачах создаётся ощущение, что таблицы созданы под способ ввода а не хранения!
18 дек 09, 12:15    [8085811]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
M0us
Member

Откуда: Moscow
Сообщений: 883
aleks2
https://www.sql.ru/forum/actualthread.aspx?tid=713546

только не нада писать триггеров.


посмотрел топик. понравились Ваши ответы.
Только UDF, думаю, имеет смысл использовать если подобные ограничения в нескольких объектах БД. Иначе смысл продить UDF на каждый чих?

CONSTRAINT - это гуд, просто не нужно вокруг него пляски с бубнами устраивать.

В данном случаем trigger уместнее.
18 дек 09, 12:52    [8086094]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
M0us
В данном случаем trigger уместнее.
Если триггер FOR INSERT, UPDATE, то в нём
IF EXISTS
(
 SELECT *
 FROM Table1 T
 WHERE EXISTS
 (
  SELECT *
  FROM Table1 TT
  WHERE TT.[key]<>T.[key]
    AND TT.[DateStart]<=T.[DateEnd]
    AND TT.[DateEnd]>=T.[DateStart]
 )
)
BEGIN
 ROLLBACK TRANSACTION;
 RAISERROR('периоды не могут пересекаться',16,1);
 RETURN;
END;
18 дек 09, 13:11    [8086233]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Кстати, может быть, выгоднее триггер INSTEAD OF INSERT, UPDATE, поскольку не будет неверных вставок/откатов.
Но тогда надо будет задействовать inserted/deleted, поскольку добавляемые строки в таблице ещё отсутствуют.
18 дек 09, 13:17    [8086294]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
aleks2
Guest
iap
M0us
В данном случаем trigger уместнее.
Если триггер FOR INSERT, UPDATE, то в нём
IF EXISTS
(
 SELECT *
 FROM Table1 T
 WHERE EXISTS
 (
  SELECT *
  FROM Table1 TT
  WHERE TT.[key]<>T.[key]
    AND TT.[DateStart]<=T.[DateEnd]
    AND TT.[DateEnd]>=T.[DateStart]
 )
)
BEGIN
 ROLLBACK TRANSACTION;
 RAISERROR('периоды не могут пересекаться',16,1);
 RETURN;
END;


Очень мило. Колбасить всю хрен-его-знает-каких-размеров таблицу гарантированным сканом при вставке одного интервала.
18 дек 09, 13:22    [8086330]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
aleks2
iap
M0us
В данном случаем trigger уместнее.
Если триггер FOR INSERT, UPDATE, то в нём
IF EXISTS
(
 SELECT *
 FROM Table1 T
 WHERE EXISTS
 (
  SELECT *
  FROM Table1 TT
  WHERE TT.[key]<>T.[key]
    AND TT.[DateStart]<=T.[DateEnd]
    AND TT.[DateEnd]>=T.[DateStart]
 )
)
BEGIN
 ROLLBACK TRANSACTION;
 RAISERROR('периоды не могут пересекаться',16,1);
 RETURN;
END;


Очень мило. Колбасить всю хрен-его-знает-каких-размеров таблицу гарантированным сканом при вставке одного интервала.
А можно по-другому?
В любом случае надо определить наличие/отсутствия пересекающегося интервала во всей таблице.
Разве не тек?
18 дек 09, 13:49    [8086548]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
Glory
Member

Откуда:
Сообщений: 104760
iap
В любом случае надо определить наличие/отсутствия пересекающегося интервала во всей таблице.
Разве не тек?

По-моему "для данного значения key не должно быть пересекающихся периодов"
18 дек 09, 13:57    [8086648]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
M0us
Member

Откуда: Moscow
Сообщений: 883
aleks2
Очень мило. Колбасить всю хрен-его-знает-каких-размеров таблицу гарантированным сканом при вставке одного интервала.


Уважаемый, я с удовольствием поменяю свое мнение.
Но как Вы сам изаметили "хрен-его-знает-каких-размеров таблицу", то и был предложен вариант без учета кол-ва записей, селективности, количества операций над таблицев в мин/час/сутки.
Без учета кол-ва пользователей и блокировок.

Автор задал вопрос - получил ответ. А мы спорим не имея деталей задачи.
Правы и Вы и Я. Просто у нас разные подходы)
18 дек 09, 13:58    [8086652]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
aleks2
Guest
iap
aleks2
iap
M0us
В данном случаем trigger уместнее.
Если триггер FOR INSERT, UPDATE, то в нём
IF EXISTS
(
 SELECT *
 FROM Table1 T
 WHERE EXISTS
 (
  SELECT *
  FROM Table1 TT
  WHERE TT.[key]<>T.[key]
    AND TT.[DateStart]<=T.[DateEnd]
    AND TT.[DateEnd]>=T.[DateStart]
 )
)
BEGIN
 ROLLBACK TRANSACTION;
 RAISERROR('периоды не могут пересекаться',16,1);
 RETURN;
END;


Очень мило. Колбасить всю хрен-его-знает-каких-размеров таблицу гарантированным сканом при вставке одного интервала.
А можно по-другому?


Нужно. Проверяют только ВСТАВЛЯЕМЫЕ интервалы на пересечение внутри вcтавляемых и с уже существующими.
18 дек 09, 14:56    [8087230]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
aleks2
Guest
M0us
aleks2
Очень мило. Колбасить всю хрен-его-знает-каких-размеров таблицу гарантированным сканом при вставке одного интервала.


Уважаемый, я с удовольствием поменяю свое мнение.
Но как Вы сам изаметили "хрен-его-знает-каких-размеров таблицу", то и был предложен вариант без учета кол-ва записей, селективности, количества операций над таблицев в мин/час/сутки.
Без учета кол-ва пользователей и блокировок.

Автор задал вопрос - получил ответ. А мы спорим не имея деталей задачи.
Правы и Вы и Я. Просто у нас разные подходы)


На вас, вроде, я еще не наезжал. Но с удовольствием наеду

M0us
Только UDF, думаю, имеет смысл использовать если подобные ограничения в нескольких объектах БД. Иначе смысл продить UDF на каждый чих?

CONSTRAINT - это гуд, просто не нужно вокруг него пляски с бубнами устраивать.

В данном случаем trigger уместнее.


Т.е. триггерный грипп (писание триггера на каждый чих) чем-то легче? Я уж молчу про "универсальную" UDF...
18 дек 09, 14:59    [8087269]     Ответить | Цитировать Сообщить модератору
 Re: Как наложить constraint на таблицу с интервалами?  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
aleks2
Нужно. Проверяют только ВСТАВЛЯЕМЫЕ интервалы на пересечение внутри вcтавляемых и с уже существующими.
А! Вот Вы про что. Туплю.
IF EXISTS
(
 SELECT *
 FROM inserted T
 WHERE EXISTS
 (
  SELECT *
  FROM Table1 TT
  WHERE TT.[key]<>T.[key]
    AND TT.[DateStart]<=T.[DateEnd]
    AND TT.[DateEnd]>=T.[DateStart]
 )
)
BEGIN
 ROLLBACK TRANSACTION;
 RAISERROR('периоды не могут пересекаться',16,1);
 RETURN;
END;
Так что ли?
18 дек 09, 15:32    [8087553]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить