是否存在允许委托人禁用/启用外键约束但不允许其他表更改的权限设置?
例如:来自'dbo'校长:
create login ref_test with password = 'test1234'
create user ref_test
exec sp_addrolemember 'db_datareader', 'ref_test'
exec sp_addrolemember 'db_datawriter', 'ref_test'
create table A (ID int not null, constraint PK_A primary key (ID))
create table B (Aid int not null, constraint FK_Aid_AID foreign key (Aid) references A(ID))
来自ref_test
登录连接:
insert A values (1)
insert B values (1)
现在,我需要能够更新FK关系中的密钥,如下所示:
-- will fail
ALTER TABLE B NOCHECK CONSTRAINT FK_Aid_AID
update A set ID = ID + 1
update B set AID = AID + 1
ALTER TABLE B WITH CHECK CHECK CONSTRAINT FK_Aid_AID
失败
Msg 1088,Level 16,State 13,Line ...
无法找到对象“B”,因为它不存在或您没有权限
如果我添加
GRANT ALTER on B to ref_test
它可以工作,但不是没有启用ALTER TABLE B DROP CONSTRAINT FK_Aid_AID
,以及在表上启用其他DDL - 添加/删除列,其他约束 - 尽管不允许FK有问题需要重新添加 - 这需要额外的GRANT REFERENCES (ID) on A to ref_test
。
答案 0 :(得分:2)
不,使用SQL Server的权限方案无法做到这一点。要执行任何特定的ALTER TABLE
语句,您需要ALTER
权限,这反过来允许您执行任何ALTER TABLE
语句,保存那些需要更新列或引用外部类型或列的语句(需要单独的权利。)
授予帐户权限的一般方法是执行他们原本无法执行的操作(并且仅那些事情)是将它们封装在在特权帐户下执行的存储过程中。因此,假设您希望为帐户提供在任何表上禁用或启用任何约束的功能,但不要执行与这些表相关的任何其他DDL:
CREATE PROCEDURE nocheck_constraint(@table SYSNAME, @constraint SYSNAME)
WITH EXECUTE AS OWNER AS
BEGIN
SET NOCOUNT ON;
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = REPLACE(REPLACE(
'ALTER TABLE $table NOCHECK CONSTRAINT $constraint;',
'$table', QUOTENAME(@table)),
'$constraint', QUOTENAME(@constraint))
;
PRINT @SQL;
EXEC(@SQL);
END;
GO
-- The following is necessary only for direct calls.
-- Note that ownership chaining will allow *any* stored procedure to call this one without
-- a separate permission check, which is a double-edged sword.
GRANT EXECUTE ON nocheck_constraint TO [unprivileged_account];
同样适用于check_constraint
。当然,您可以根据需要使其更精细。
我通过利用EXECUTE AS OWNER
在这里采取了一个潜在的危险捷径,因此我可以在没有安全限制的情况下执行动态SQL。如果您无法完全控制数据库及其中创建的所有过程,则这不仅会对数据库的安全性产生影响,还会对服务器的其余部分产生一些影响。在这种情况下,您可能希望考虑签署该过程并使用代理。我没有将这一切都散列到这里,而是引用你Erland Sommarskog's excellent writeup on the matter。
答案 1 :(得分:0)
我有一些用户,我不会在Management Studio中授予权限以更改表的列的扩展属性。 因此,当对该用户的表赋予ALTER权限时,可以看到Keys,Indexes,Constraint,甚至无法更改。所以不要看到在sys.check_constraint,sys.foreignkeys,sys.key_constraint中的SELECT上有DENY .... 因此,可能在sys.columns,sys.foreignkeys,sys.check_constraint上使用ALTER ON表和DENY和GRANT的某种组合....可以允许主体禁用/启用外键约束,但不允许其他表改变
答案 2 :(得分:-1)
Msg 1088,Level 16,State 13,Line ... 无法找到对象“B”,因为它不存在或您没有权限
如果我在管理工作室这样做,我会注意到下一步: 如果我对特定表没有SELECT权限则会出现问题,所有ForeignKey都会消失 如果我没有SELECT权限,那么在CheckExistingData上创建或启用如果是,则应该在No中更改,并且EnforceForeignKey Constraint可以从Yes更改为No,或者相反 所以: 1.或表上的SELECT权限(CheckExistingDataOnCreatinon需要或如果设置为Yes则需要重新启用) 2.或CheckExistingDataOnCreation或Reanablig(再次创建)设置为否