2009-10-27 5 views
6

Может быть, это глупые вопросы, но могу ли я защитить ряд данных в базе данных SQL Server от их удаления или обновления без установки прав пользователя?SQL: возможна запись строки «Write Protect»?

Это для строки данных по умолчанию, на которую можно ссылаться для значений по умолчанию?

Благодаря

+0

Почему вы не хотите устанавливать разрешения пользователя? – SLaks

+0

Вероятно, это не очень хороший ответ, но его база данных с единственным пользователем-администратором – Belliez

ответ

1

Один из возможных подходов, что я когда-то описано в моем блоге:

«Предположим, что вам необходимо соблюдение следующих бизнес-правило: контракты не могут быть изменены после того, как вы начали работать на них (допустим, что что особенно бизнес работает в идеальном мире) Вы можете использовать столбец ROWVERSION, а сохраненный вычисляемые один, и ограничение внешнего ключа для реализации этого правила -. Using ROWVERSION to enforce business rules

+0

Это сладкая техника. –

+0

Немного перехитрить его ситуацию (так как вам понадобится столбец RowVersion для всех строк, а не только первая строка, которую он пытается защитить), но это сработает! –

1

Вы могли бы сделать триггер, который вызывает ошибку, если эта строка обновляется или удаляется.

+0

Это не будет автоматически проверять perms. – DVK

+3

Триггеры игнорируются при выполнении таблицы усечения. – sisve

+0

Вам не нужен отдельный уровень разрешений для обрезания таблицы, чем для удаления всех строк? Если это так, он может разрешить отдельно устанавливать всех пользователей, кроме admin (как и должно быть). – DVK

0

Предположим, что ваш MyTable находится на Primary.

Поместите первую строку в новую таблицу MyTableReadOnly, переместите эту таблицу в свою собственную группу файлов и сделайте группу файлов только для чтения.

Удалите первую строку из MyTable

Теперь создать представление, что

SELECT Columns From MyTableNew 
UNION 
SELECT Columns From MyTable 

доступ все через представление. Если вы хотите обновить или удалить из представления, вы можете сделать это в MyTable и игнорировать что-либо для MyTableNew. Если вы хотите работать с представлением, вы можете использовать триггеры INSTEAD-OF.

+0

Две проблемы с этим подходом: вы должны сохранить свой вид (например, TDD вместо данных), если список ограниченных строк изменится. И вы должны создать новое представление для каждого отдельного набора perms (тот же недостаток, что и мой собственный подход, как отметил Питер). – DVK

0
  • Создайте вторую таблицу, в которой есть строки с теми же уникальными идентификаторами, что и строки, которые вы пытаетесь защитить.

  • Разрешение, которое ВТОРАЯ стол, как вы хотите

  • Добавить триггер на первом столе, который будет удалять/обновлять обе таблицы, если соответствующая строка существует во второй таблице.

Таким образом, если у вас нет завивки на втором столе, вы не сможете изменить «связанную» строку, как триггер будет прекращен из-за нарушения прав доступа на вторую таблице

NOTE : Контраст этого метода с другими основными методами (с использованием VIEW) заключается в том, что он позволяет легко поддерживать набор «фиксированных» строк в отличие от подхода VIEW и избегает различных проблем с производительностью, обычно связанных с представлениями.

+0

Просто обратите внимание: для решения проблемы Саймона Свенссона относительно другого решения, упоминающего триггер, усечение таблицы не является проблемой, поскольку для ее удаления требуется отдельное perms. – DVK

+0

Это хорошо. Он позволяет предоставлять разрешения для набора строк. Хотя для каждой отдельной пары (набор строк, разрешений) вам понадобится другая таблица. Например, если у двух пользователей были разрешения на уровне строк, но не на одном и том же наборе строк, для каждого из них потребуется отдельная таблица управления. Из-за того, что я неправильно понял реализацию? –

+0

Да, это так. Но это единственный подход, который я знаю **, который использует собственные разрешения на уровне таблиц **. Все, что требуется, требует либо прав на хранение в таблицах (например, триггер проверяет ваш идентификатор пользователя на таблицу, содержащую идентификаторы rowID, сопоставленные с разрешениями, возможно, используя группы пользователей БД, если это возможно, или непосредственно к идентификаторам пользователей, если нет). – DVK

2

Сделайте это реляционной целостностью - делать НЕ использования триггеров, как они всегда являются настоящей болью, чтобы поддерживать их (они имеют свое место, а не здесь). egrity сделает все, что вам нужно.

Использование реляционной целостности может быть довольно элегантным, но то, что вам нужно сделать, является слегка контринтуитивным, поэтому его легко пропустить.

Создайте основную таблицу, tblMain, с числовым первичным ключом.Для простоты я проверил это с таблицей с одной колонкой, intID, и я заполнил ее значениями 0,1 и 2.

Далее создайте вторую таблицу tblGuard с таким же числовым первичным ключом. Я добавил одну строку в эту таблицу, значение 1.

Теперь бит обратной логики. Создание внешнего ключа на tblGuard таблице , которые ссылаются на tblMain таблицу

ALTER TABLE [dbo].[tblGuard] ADD 
    CONSTRAINT [FK_tblGuard_tblMain] FOREIGN KEY 
    (
     [intID] 
    ) REFERENCES [dbo].[tblMain] (
     [intID] 
    ) 

Ограничение будет гарантировать, что строка со значением intID 1 не может быть удален из таблицы tblMain, так как таблица tblGuard ссылочной целостности требует, чтобы значения 1 существует в tblMain. Это работает с удалением и усечением.

+0

Это только предотвращает удаление, оно не защищает вашу строку от обновлений. Требование: «защитить строку данных в базе данных SQL Server от удаления или обновления» –

0

Я говорю об этом «программно». Например, пусть строка с идентификатором 1 всегда является строкой по умолчанию, а затем добавляет во все запросы UPDATE или DELETE «WHERE id! = 1» или выполняет эквивалент на любом языке, который вы используете для написания вашей логики (PHP, C, VB и т. д.)