检查Ms Sql Server 2005中的约束

时间:2010-08-29 17:06:35

标签: sql-server sql-server-2005 triggers constraints

我正在尝试添加一个检查约束,如果在更新后新值(已插入)大于已存储在表中的旧值,则检查其真实性。

例如,我有一个“价格”列,已经存储了值100,如果更新自带101,则可以,如果99出现,那么我的约束应该拒绝更新过程。可以使用检查约束来实现这种行为,还是应该尝试使用触发器或函数?

请就此建议我......

谢谢,  米尔恰

2 个答案:

答案 0 :(得分:2)

检查约束无法访问列的先前值。您需要使用触发器。

这种触发器的一个例子是

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

答案 1 :(得分:0)

触发器作为快速修复启动,并以维护噩梦结束。触发器的两大问题是:

  • 很难看到何时调用触发器。您可以轻松编写更新语句,而无需知道将运行触发器。
  • 当触发器开始触发其他触发器时,很难说明会发生什么。

作为替代方法,在存储过程中包装对表的访问。例如:

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

存储过程非常容易阅读。与触发器相比,它们会让您减轻头痛。您可以通过不向任何用户授予UPDATE表的权限来强制使用存储过程。无论如何,这是一个很好的做法。