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

create table dbo.p(id_p int, r_min int, r_max int);
go

create table dbo.c(id_p int /* FK dbo.p */, id_c int, r_val int);
go


Как запретить в колонку c.r_val записывать значение выходящее за пределы диапазона p.r_min и p.r_max.
Как сделать, чтобы при изменении p.r_min и p.r_max осуществлялась проверка, что все c.r_val лежат в измененном диапазоне, иначе не давать изменять r_min и r_max.

Спасибо.
29 июн 15, 16:08    [17828931]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать такое ограничение?  [new]
Glory
Member

Откуда:
Сообщений: 104760
Это называется триггер
29 июн 15, 16:09    [17828938]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать такое ограничение?  [new]
Gviber
Member

Откуда:
Сообщений: 124
Не стал особо вникать. По-моему тут тригер INSTEAD OF
29 июн 15, 16:11    [17828952]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать такое ограничение?  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1446
## do diezzz ##,


create table dbo.p(id_p int, r_min int, r_max int);
go

create function chk_fn_constraint (
      @value int
)
returns int
as begin
declare @x int
set @x = 0

if exists (select 1 from dbo.p where @value between r_min and r_max)
  set @x = 1

return @x
end
go;

create table dbo.c(id_p int, id_c int, r_val int check(dbo.chk_fn_constraint(r_val) = 1);
go


но будет медленней чем триггер instead of
так что вам правильно советуют использовать именно их
29 июн 15, 16:25    [17829017]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать такое ограничение?  [new]
Павел Воронцов
Member

Откуда: Новосибирск
Сообщений: 2385
Блог
## do diezzz ##,

можно еще UDF check constraint попробовать. Но триггер лучше.
29 июн 15, 16:26    [17829020]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать такое ограничение?  [new]
## do diezzz ##
Guest
felix_ff, спасибо.

Gviber, сделал AFTER триггером в котором делаю throw, а почему советуете именно INSTEAD OF?
29 июн 15, 17:00    [17829192]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать такое ограничение?  [new]
## do diezzz ##
Guest
Glory, Павел Воронцов,

спасибо!
29 июн 15, 17:01    [17829199]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать такое ограничение?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
## do diezzz ##, дабы журнал транзакций не напрягать.
29 июн 15, 17:08    [17829238]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать такое ограничение?  [new]
## do diezzz ##
Guest
Владислав Колосов
## do diezzz ##, дабы журнал транзакций не напрягать.


А в read committed не получится так, что проверка в триггере прошла, потом ниже по триггеру insert into dbo.c (/*список колонок*/) select /*список колонок*/ from inserted или update. а между проверкой и insert или update кто-то поменял значения r_min и r_max и в итоге будет рассинхрон?
29 июн 15, 17:13    [17829282]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать такое ограничение?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31435
Владислав Колосов
## do diezzz ##, дабы журнал транзакций не напрягать.
В данном случае требуется аналог констрейна, проверки.

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

Зачем везде пихать триггеры INSTEAD OF, они же сложнее, потенциально больше ошибок, их нужно менять при изменении таблицы...
30 июн 15, 00:23    [17830752]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить