9

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

如果 id 为 0,1 或 2,我想(例如)拒绝删除行

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

谢谢!

编辑:

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

编辑2:

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

4

7 回答 7

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);

现在没有人可以删除Accountsid 值为 0、1 或 2 的行,除非他们先删除NoKillI. 您可以使用 SQL 权限限制对依赖表的删除。

于 2008-12-14T20:04:12.130 回答
5

您可以通过为相关表编写一个在 DELETE 上触发的数据库触发器来完成此操作。如果 ID 无效,它需要做的就是抛出异常。

于 2008-12-14T19:45:40.903 回答
3

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

  1. 添加一个存储过程,允许用户删除他们想要的行,但根据您自己的规则禁止您想要的任何行。然后拒绝对表的删除访问,并允许对存储过程的执行访问
  2. 添加带有外键引用的辅助表,调用表 MasterAccounts 或类似的表,拒绝更新/删除对该表的访问,并将对该表的引用添加到相关帐户,这将防止任何人删除帐户,只要有此表对它的引用
  3. 按照OrbMan的建议添加触发器
  4. 添加可以删除行的视图,使视图跳过所有不允许删除的帐户,拒绝对主表的删除访问,并允许删除访问查看

话虽如此,如果您的用户有足够的访问权限通过 SQL 与您的数据库对话,那么您实际上只是在自找麻烦。您应该加强安全性,并且只允许通过您的应用程序和已建立的协议访问数据库。然后你有很多选择来避免这样的问题。

于 2008-12-14T20:15:21.093 回答
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
于 2008-12-14T22:16:22.660 回答
0

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

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

于 2008-12-14T20:55:58.343 回答
0

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

对于Tbl_Account无法删除的每条记录,我会在Tbl_AccountMaster其中添加Tbl_Account.id_Account一条外键记录。Tbl_AccountMaster不可用于更新,除非由数据库管理员提供。然后没有其他人可以删除Tbl_Account链接到的记录Tbl_AccountMaster

编辑:我刚刚注意到这里提出了同样的想法。谢谢比尔!

于 2008-12-14T22:37:28.980 回答
-1

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

于 2008-12-14T19:36:48.503 回答