MSSQL触发器或约束,以防止或允许基于列值的更新/删除

时间:2016-06-03 08:21:13

标签: sql-server

我有一个Customers表,当行的Status列不是1时,我想阻止更新/插入。

在服务器上直接创建这种功能的最佳方法是什么?

4 个答案:

答案 0 :(得分:2)

您可以创建存储过程并强制其使用以更新表。

create procedure updateCustomers @custID int,@newValue nvarchar(50) 
with execute as superUser 
as

update customers
set someColumn=@newValue
where custID=@custID and status=1

答案 1 :(得分:0)

您可以尝试这样:

CREATE TRIGGER [dbo].[PreventUpdate]
ON [dbo].[Customers]
INSTEAD OF UPDATE
AS 
BEGIN
  SET NOCOUNT ON;

  IF EXISTS 
  (
     SELECT 1 FROM Customers c
       WHERE c.Status <> 1 )
  BEGIN
     RAISERROR(...);
  END
  ELSE
  BEGIN
     --You update code
  END
END
GO

答案 2 :(得分:0)

1)如果要在新的Status为diff时阻止任何INSERT / UPDATE操作。然后跟随触发器将阻止此类操作。 无论如何,这个要求毫无意义,因为使用检查约束非常简单:ALTER TABLE dbo.Customer ADD CONSTRAINT ... CHECK ([Status] <> 1)

CREATE TRIGGER dbo.trgIU_Customer_PreventIU
ON dbo.Customer
AFTER INSERT, UPDATE
AS
BEGIN
    SET NOCOUNT ON

    IF EXISTS(SELECT * FROM inserted i WHERE i.[Status] IS NOT NULL AND i.[Status] <> 1)
    BEGIN
        RAISERROR('Can''t insert or update rows with Status <> 1', 16, 1)
        ROLLBACK
    END
END

2)但是,如果您想在当前[Status]为1时完全避免任何更新,则可以使用以下触发器:

CREATE TRIGGER dbo.trgU_Customer_PreventU
ON dbo.Customer
AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON

    IF EXISTS(SELECT * FROM deleted d WHERE d.[Status] = 1)
    BEGIN
        RAISERROR('Can''t update rows with Status = 1', 16, 1)
        ROLLBACK
    END
END

答案 3 :(得分:0)

  

什么是最好的方式

请勿使用触发器。存在触发器以强制引用完整性,并且将它们用于其他目的将导致眼泪。

拒绝用户对表的权限,而是提供存储过程,例如doublet28建议。这使您有机会提供有意义的错误消息,并使DBA可以自由更新表而不会触发触发器(这将需要更快的时间)。