Sql Server: как записать триггер на таблицу с отключенным SELECT - PullRequest
3 голосов
/ 06 мая 2009

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

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

Это дает мне ошибку, хотя, говоря: "ВЫБРАН РАЗРЕШЕНЫ РАЗРЕШЕНИЯ", я думаю, из-за ВЫБРАТЬ ИЗ ВСТАВЛЕННЫХ.

Как я могу запретить SELECT, но разрешить триггеру SELECT из псевдотесты INSERTED?

Заранее спасибо!

Ответы [ 4 ]

2 голосов
/ 22 мая 2009

Рассмотрите возможность добавления предложения EXECUTE AS , чтобы триггер работал с разрешениями владельца схемы.

CREATE TRIGGER [dbo].[TR_Product_Update] ON [Product]
   WITH EXECUTE AS OWNER
   AFTER UPDATE
AS
SELECT ProductId
FROM INSERTED
1 голос
/ 06 мая 2009

Почему вы отказались от выбора? Как насчет того, чтобы просто не предоставлять им выбор? Существует тонкая разница между отказом в выборе и просто не предоставлением им этого. Кроме того, если вы отказали в выборе какой-либо роли системного уровня, это, вероятно, также будет частью проблемы.

- EDIT -

В комментариях вы спрашивали, есть ли у SQL Server контекстная информация. 2005 год, и вы можете увидеть, как его использовать здесь .

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

0 голосов
/ 22 мая 2009

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

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

DROP DATABASE triggerPermissionTest<br> CREATE DATABASE triggerPermissionTest<br> GO<br> USE triggerPermissionTest<br> GO<br> CREATE USER foo FROM LOGIN tester<br> GO<br> CREATE TABLE triggerTable (id int)<br> GO<br> DENY SELECT ON triggerTable to foo<br> GRANT UPDATE ON triggerTable to foo<br> GO<br> CREATE TRIGGER execAsTrigger ON triggerTable<br> AFTER UPDATE AS SELECT * FROM triggerTable <br> GO<br> INSERT INTO triggerTable VALUES (1)<br> GO<br>

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

UPDATE triggerTable SET id = 2<br> GO<br> UPDATE triggerTable SET id = id *2<br> GO<br>

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

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

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

0 голосов
/ 06 мая 2009

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

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

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

...