您好我有一张表,我已拒绝向用户发送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语句是权限问题的原因。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top