SQL: возможна ли строка данных "Защита от записи"?

могут быть глупые вопросы, но могу ли я защитить строку данных в базе данных SQL Server от удаления или обновления без установки разрешений пользователя?

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

спасибо

6 ответов


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

"предположим, что вам нужно применить следующее бизнес-правило: контракты не могут быть изменены после того, как вы начали работать над ними (предположим, что этот конкретный бизнес работает в идеальном мире). Для реализации этого правила можно использовать столбец ROWVERSION, сохраненный вычисляемый и ограничение внешнего ключа -использование ROWVERSION для обеспечения соблюдения бизнес-правил


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

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

создайте свою основную таблицу 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. Это работает с удалениями и усечениями.


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


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

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

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

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

SELECT Columns From MyTableNew
UNION
SELECT Columns From MyTable

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


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

  • разрешение, что вторая таблица, Как вы хотите

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

таким образом, если у вас нет Пермь на второй таблице, вы не сможете изменить "связанные" строки как триггер завершится из-за нарушения разрешений на второй таблице

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


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