Sql Server:如何在拒绝SELECT的表上写入触发器
-
06-07-2019 - |
题
您好我有一张表,我已拒绝向用户发送SELECT privs。
该表有一个引用INSERTED表的触发器,基本上是做
AFTER UPDATE SET <table>.[UPDATED] = getdate()
WHERE ROWID IN SELECT ROWID FROM INSERTED
它给了我一个错误,说“SELECT PERMISSIONS DENIED”,我猜是因为SELECT FROM INSERTED。
如何保持SELECT拒绝,但允许触发器从INSERTED伪指令中选择?
提前致谢!
解决方案
考虑添加 EXECUTE AS 子句,以便触发器以架构所有者的权限运行。
CREATE TRIGGER [dbo].[TR_Product_Update] ON [Product]
WITH EXECUTE AS OWNER
AFTER UPDATE
AS
SELECT ProductId
FROM INSERTED
其他提示
你为什么拒绝选择?那不是不给他们选择呢?拒绝选择和不批准选择之间存在细微差别。此外,如果您拒绝选择任何系统级角色,那么这也可能是问题的一部分。
<强> - 编辑 - 强>
在评论中,您询问SQL Server是否有上下文信息。 2005年,你可以看到如何使用它这里
会话变量&#8211; Context_Info:Session是任何编程语言中的强大工具。 SQL-Server不是一个完整的fledge编程语言,但它确实支持当前会话或连接的会话变量。它将会话值存储在128字节的二进制信息中。
加入到插入的表中,而不是像:
update t1
set updated = getdate()
from table1 t1
join inserted i
on i.rowid = t1.rowid
无论如何,这可能也会比subselect更好。
我怀疑你的问题是你的UPDATE语句本身需要SELECT权限。
我创建了一个测试数据库,如下所示:
<代码>
DROP DATABASE triggerPermissionTest
CREATE DATABASE triggerPermissionTest
GO结果
USE triggerPermissionTest
GO结果
从LOGIN tester
创建USER foo
GO结果
CREATE TABLE triggerTable(id int)
GO结果
DENY SELECT ON触发器表到foo
授予更新触发器表格foo
GO结果
创建TRIGGER execAsTrigger ON triggerTable
更新后选择*来自triggerTable
GO结果
INSERT INTO triggerTable VALUES(1)
GO结果
代码>
并使用'tester'登录尝试以下Update语句:
<代码>
UPDATE triggerTable SET id = 2
GO结果
UPDATE triggerTable SET id = id * 2
GO结果
代码>
第一个执行正常并且触发器执行(将来自triggerTable的select *的结果提供给没有选择权限的用户,证明它设法进行选择)。
第二个给出了一个错误,指出我对triggerTable没有select权限(因为它需要从triggerTable中选择以获取id的值来进行更新)。
这使我得出结论,触发器是问题的偶然因素,而UPDATE语句是权限问题的原因。