Servidor SQL: como escrever gatilho em uma tabela com seleção negado
-
06-07-2019 - |
Pergunta
Olá, tenho uma tabela na qual neguei a Select Privs a um usuário.
Esta tabela tem um gatilho que faz referência à tabela inserida, basicamente fazendo um
AFTER UPDATE SET <table>.[UPDATED] = getdate()
WHERE ROWID IN SELECT ROWID FROM INSERTED
Isso está me dando um erro, dizendo "Permissões selecionadas negadas", acho que por causa da seleção do inserido.
Como posso manter o seleto negar, mas permitir que o gatilho selecione a partir do pseudootável inserido?
Desde já, obrigado!
Solução
Considere adicionar um Execute como Cláusula para que o gatilho seja executado com as permissões do proprietário do esquema.
CREATE TRIGGER [dbo].[TR_Product_Update] ON [Product]
WITH EXECUTE AS OWNER
AFTER UPDATE
AS
SELECT ProductId
FROM INSERTED
Outras dicas
Por que você negou selecionar? Que tal não conceder a eles selecionar para eles? Há uma diferença sutil entre negar a seleção e simplesmente não conceder a eles. Além disso, se você negar a seleção para qualquer uma das funções de nível do sistema, isso provavelmente também fará parte do problema.
--EDITAR--
Nos comentários, você perguntou se o SQL Server tem ou não informações de contexto. 2005 faz e você pode ver como usá -lo aqui.
Variável de sessão - context_info: sessão é uma ferramenta poderosa em qualquer linguagem de programação. O SQL-SERVER não é uma linguagem de programação completa, mas oferece suporte à variável da sessão para a sessão ou conexão atual. Ele armazena o valor da sessão em 128 byte de informações binárias.
junte -se à tabela inserida em vez de algo como:
update t1
set updated = getdate()
from table1 t1
join inserted i
on i.rowid = t1.rowid
Isso provavelmente também se aprimorará melhor do que um subseleto de qualquer maneira.
Suspeito que seu problema seja que sua declaração de atualização requer a permissão de seleção.
Eu criei um banco de dados de teste da seguinte maneira:
DROP DATABASE triggerPermissionTest
CREATE DATABASE triggerPermissionTest
GO
USE triggerPermissionTest
GO
CREATE USER foo FROM LOGIN tester
GO
CREATE TABLE triggerTable (id int)
GO
DENY SELECT ON triggerTable to foo
GRANT UPDATE ON triggerTable to foo
GO
CREATE TRIGGER execAsTrigger ON triggerTable
AFTER UPDATE AS SELECT * FROM triggerTable
GO
INSERT INTO triggerTable VALUES (1)
GO
e tentei as seguintes instruções de atualização com o login 'testador':
UPDATE triggerTable SET id = 2
GO
UPDATE triggerTable SET id = id *2
GO
O primeiro é executado bem e o gatilho é executado (fornecendo os resultados de seleção * de trigertable para o usuário sem permissões selecionadas, demonstrando que ele conseguiu fazer uma seleção).
O segundo me dá um erro afirmando que não tenho permissão selecionada sobre o Trigertable (porque ele precisa selecionar de Trriggertable para obter o valor do ID para fazer a atualização).
Isso me leva a concluir que o gatilho é incidental ao problema, e a declaração de atualização é a causa da questão da permissão.