Проверьте ограничения в Ms Sql Sever 2005 - PullRequest
3 голосов
/ 29 августа 2010

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

Например, у меня есть столбец «цена», в котором уже хранится значение 100, если обновление идет с 101, все в порядке, если приходит 99, тогда мое ограничение должно отклонить процесс обновления. Может ли это быть достигнуто с помощью проверочных ограничений или я должен попытаться использовать триггеры или функции?

Пожалуйста, сообщите мне об этом ...

Спасибо, Мирча

Ответы [ 2 ]

2 голосов
/ 29 августа 2010

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

Примером такого триггера будет

CREATE TRIGGER DisallowPriceDecrease
ON Products
AFTER UPDATE
AS
IF NOT UPDATE(price) 
   RETURN

IF EXISTS(SELECT * FROM inserted i 
                     JOIN deleted d 
                     ON i.primarykey = d.primarykey 
                      AND i.price< d.price)
BEGIN
    ROLLBACK TRANSACTION
    RAISERROR('Prices may not be decreased', 16, 1)
END
0 голосов
/ 29 августа 2010

Триггеры начинаются как быстрое решение и заканчиваются кошмаром обслуживания. Две большие проблемы с триггерами:

  • Трудно увидеть, когда вызывается триггер. Вы можете легко написать оператор обновления, не зная, что триггер запустится.
  • Когда триггеры начинают запускать другие триггеры, становится трудно сказать, что произойдет.

В качестве альтернативы, оберните доступ к таблице в хранимой процедуре. Например:

create table TestTable (productId int, price numeric(6,2))
insert into TestTable (productId, price) values (1,5.0)
go
create procedure dbo.IncreasePrice(
    @productId int,
    @newPrice numeric(6,2))
with execute as owner
as
begin
    update  dbo.TestTable
    set     price = @newPrice
    where   productId = @productId
            and price <= @newPrice

    return @@ROWCOUNT
end
go

Теперь, если вы попытаетесь уменьшить цену, процедура завершится ошибкой и вернет 0:

exec IncreasePrice 1, 4.0
select * from TestTable --> 1, 5.00
exec IncreasePrice 1, 6.0
select * from TestTable --> 1, 6.00

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

...