Использование триггеров для принудительного ограничения - PullRequest
1 голос
/ 09 января 2009

Я пытаюсь обеспечить целостность таблицы способом, который, я думаю, не может ограничить ...

CREATE TABLE myData
(
   id             INTEGER IDENTITY(1,1) NOT NULL,
   fk_item_id     INTEGER               NOT NULL,
   valid_from     DATETIME              NOT NULL,
   invlaid_from   DATETIME              NOT NULL
)

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

Примечание:

invalid_from - момент, следующий сразу же после действительного периода.
Это означает, что следующие два периода хороши ...

  • '2008 Jan 01 00:00' -> '2008 Feb 01 00:00' (все января)
  • '2008 Feb 01 00:00' -> '2008 Mar 01 00:00' (весь февраль)

Я могу проверить это правило в триггере. Однако когда триггер обнаруживает недопустимую вставку / обновление, каков наилучший способ предотвратить возникновение «незаконных» вставок / обновлений?

(Если вставлено включает две действительные записи и две недействительные записи, могу ли я остановить только две недействительные записи?)

Приветствия
Демс.

EDIT:

В моем случае ограничение с использованием функции работало хорошо. Но я так и не понял, почему RAISERROR не работает в триггерной версии.

Я думал, что это потому, что триггер - это ПОСЛЕ триггера, и что мне нужен триггер ДО, но это не вариант ...

Ответы [ 4 ]

3 голосов
/ 09 января 2009

Не удаляйте записи из вставленной таблицы ... это молчаливая ошибка. Дорога в ад вымощена частичными коммитами.

Вам необходимо RAISERROR , что, по сути, и делает ограничение .

3 голосов
/ 09 января 2009

Вы не можете удалить непосредственно из вставленного (обновления логических таблиц приводят к ошибке), но вы можете присоединиться к исходной таблице, как показано ниже

create table triggertest (id int null, val varchar(20))
Go
create trigger after  on [dbo].triggertest
for Update  
as
Begin

    delete tt from triggertest tt inner join 
    inserted i on tt.id = i.id 
    where i.id = 9

End
GO
insert into triggertest values (1,'x')
insert into triggertest values (2,'y')
Update triggertest set id = 9 where id = 2
select * from triggertest
1, x

Кроме того, вам не нужно идти по триггерному маршруту, вы также можете привязать проверочное ограничение к возвращаемому значению функции

Alter table myData WITH NOCHECK add 
Constraint  CHK_VALID CHECK (dbo.fx_CheckValid(id, valid_from , invalid_from) = 1 );
0 голосов
/ 09 января 2009

Ваш триггер может изменить valid_from и / или invlaid_from DATETIME s "незаконных" записей на специальные значения. Последующий этап очистки может выявить «незаконные» записи.

0 голосов
/ 09 января 2009

Выдает ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...