有没有办法使用约束和触发器来避免特定表上的行删除?

时间:2008-12-14 19:30:46

标签: sql sql-server database constraints

有没有办法使用约束来避免在特定表上删除行?

如果id为0,1或2

,我想(例如)拒绝删除行

这是为了避免用户删除某个应用程序的主帐户,即使有人(直接使用sql)直接尝试使用sql,我也想避免使用它。

谢谢!

修改

这个问题的整个想法不是触及应用程序。这不是安全问题,我只需要知道是否可以使用约束或SQL Server所具有的任何其他东西来执行我所要求的(它不需要是标准的数据库解决方案)。

编辑2:

非常非常感谢代码示例:D

7 个答案:

答案 0 :(得分:10)

至于在约束中强制执行此操作,我的解决方案是创建一个从属表,因此无法删除引用的行。

CREATE TABLE NoKillI (
  id INT NOT NULL, FOREIGN KEY (id) REFERENCES Accounts(id) ON DELETE RESTRICT
);
INSERT INTO NoKillI (id) VALUES (0);
INSERT INTO NoKillI (id) VALUES (1);
INSERT INTO NoKillI (id) VALUES (2);

现在没有人可以删除id为0,1或2的Accounts中的行,除非他们首先删除NoKillI中的相应行。您可以使用SQL权限限制对依赖表的删除。

答案 1 :(得分:5)

您可以通过编写针对相关表格的DELETE触发的数据库触发器来执行此操作。如果ID无效,它需要做的就是抛出异常。

答案 2 :(得分:3)

如果您不信任您的用户,请添加安全性。

  1. 添加一个存储过程,允许用户删除他们想要的行,但根据您自己的规则禁止任何您想要的行。然后拒绝对表的删除访问,并允许对sproc的执行访问
  2. 添加具有外键引用的辅助表,调用表MasterAccounts或类似的,拒绝对此表的更新/删除访问权限,并将对它的引用添加到相关帐户,这将阻止任何人删除帐户因为这张表有一个参考
  3. 添加触发器,OrbMan建议
  4. 添加一个可以删除行的视图,使视图跳过所有不允许删除的帐户,拒绝删除对主表的访问权限,并允许删除访问权限以查看
  5. 话虽如此,如果您的用户有足够的访问权限通过SQL与您的数据库通信,那么您真的只是在寻找麻烦。您应该加强安全性,并且只允许通过您的应用程序和已建立的协议访问数据库。那么你有很多选择可以避免这样的问题。

答案 3 :(得分:1)

我正在使用以下触发器:

CREATE TRIGGER [dbo].[mytable_trd] ON [dbo].[mytable]
WITH EXECUTE AS CALLER
INSTEAD OF DELETE
AS
BEGIN
SET NOCOUNT ON
DECLARE @tn varchar(255)
SELECT @tn = object_name(parent_obj)
FROM sysobjects
WHERE id = @@procid;

SET @tn = 'Deletes not allowed for this table: ' + @tn;
-- Add your code for checking the values from deleted
IF EXISTS(select * from deleted where mycolumn = 1)
  RAISERROR (@tn, 16, 1)    
END
GO

答案 4 :(得分:0)

你确定你永远不会希望任何人删除这些行吗?甚至你自己,还是dba?还是dbms维护工作?

如果它只是某些用户,那么您需要具有权限的用户表,以便可以在触发器中查询它以区分未授权用户和授权用户。

答案 5 :(得分:0)

我更喜欢的解决方案使用关系模型及其完整性规则。

对于Tbl_Account中无法删除的每条记录,我会在Tbl_AccountMaster中添加一条记录,其中Tbl_Account.id_Account是外键。除了数据库管理员之外,Tbl_AccountMaster不可用于更新。然后,其他任何人都无法删除与Tbl_Account链接的Tbl_AccountMaster的记录。

编辑:我刚刚注意到同样的想法被开发here。谢谢比尔!

答案 6 :(得分:-1)

您可以尝试使用检查以确保用户不会尝试删除您的主帐户的功能来过滤您的查询。