SQL-сервер:как написать триггер для таблицы с запрещенным SELECT

StackOverflow https://stackoverflow.com/questions/830662

Вопрос

Здравствуйте, у меня есть таблица, в которой я запретил пользователю права доступа SELECT.
Эта таблица имеет триггер, который ссылается на таблицу INSERTED, по сути выполняя

AFTER UPDATE SET <table>.[UPDATED] = getdate() 
  WHERE ROWID IN SELECT ROWID FROM INSERTED

Однако он выдает мне ошибку: «SELECT PERMISSIONS DENIED», я предполагаю, что из-за SELECT FROM INSERTED.

Как я могу запретить SELECT, но разрешить триггеру 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 есть, и вы можете увидеть, как его использовать. здесь.

Переменная сеанса – Context_Info:Сессия — мощный инструмент на любом языке программирования.SQL-Server не является полноценным языком программирования, но он поддерживает переменную сеанса для текущего сеанса или соединения.Он хранит значение сеанса в 128 байтах двоичной информации.

вместо этого присоединитесь к вставленной таблице:

update t1
set updated = getdate()
from table1 t1
join inserted i
on i.rowid = t1.rowid

В любом случае, это, вероятно, также будет лучше, чем выборка.

Я подозреваю, что ваша проблема в том, что для вашего оператора UPDATE требуется разрешение SELECT.

Я создал тестовую базу данных следующим образом:

<код> DROP DATABASE triggerPermissionTest
CREATE DATABASE triggerPermissionTest
GO
USE triggerPermissionTest
GO
СОЗДАТЬ ПОЛЬЗОВАТЕЛЯ foo FROM LOGIN tester
GO
CREATE TABLE triggerTable (id int)
GO
DENY SELECT ON triggerTable для foo
ОБНОВЛЕНИЕ ГРАНТА НА триггере для foo
GO
CREATE TRIGGER execAsTrigger ON TriggerTable
ПОСЛЕ ОБНОВЛЕНИЯ КАК ВЫБРАТЬ * ИЗ TriggerTable
GO
INSERT INTO триггерных значений (1)
GO

и попробовал следующие операторы Update с логином "tester":

<код> ОБНОВЛЕНИЕ триггерной таблицы SET id = 2
GO
ОБНОВЛЕНИЕ триггерной таблицы SET id = id * 2
GO

Первый выполняется нормально, а триггер выполняется (предоставляя результаты select * from triggerTable пользователю без разрешений select, демонстрируя, что ему удалось сделать выбор).

Второй выводит сообщение об ошибке, в котором говорится, что у меня нет разрешения на выбор для triggerTable (потому что он должен выбирать из triggerTable, чтобы получить значение id для обновления).

Это приводит меня к выводу, что триггер случайный для проблемы, а оператор UPDATE является причиной проблемы с разрешениями.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top