Есть ли способ избежать удаления строки в конкретной таблице, используя ограничения или триггеры? - PullRequest
9 голосов
/ 14 декабря 2008

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

Я бы хотел (например) отказать в удалении строки, если идентификатор равен 0,1 или 2

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

Спасибо!

EDIT:

Вся идея этого вопроса не в том, чтобы касаться приложения. Это не вопрос безопасности, мне просто нужно знать, возможно ли выполнить то, что я просил, с помощью ограничений или любой другой вещи, которая есть в SQL Server (это не обязательно должно быть стандартным решением БД).

РЕДАКТИРОВАТЬ 2:

Примеры кода очень и очень ценятся: D

Ответы [ 7 ]

10 голосов
/ 14 декабря 2008

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

CREATE TABLE NoKillI (
  id INT NOT NULL, FOREIGN KEY (id) REFERENCES Accounts(id) ON DELETE RESTRICT
);
INSERT INTO NoKillI (id) VALUES (0);
INSERT INTO NoKillI (id) VALUES (1);
INSERT INTO NoKillI (id) VALUES (2);

Теперь никто не может удалить строки в Accounts со значениями идентификатора 0, 1 или 2, если только они сначала не удалили соответствующие строки в NoKillI. Вы можете ограничить удаление для зависимой таблицы, используя привилегии SQL.

5 голосов
/ 14 декабря 2008

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

3 голосов
/ 14 декабря 2008

Если вы не доверяете своим пользователям, добавьте безопасность.

  1. Добавьте хранимую процедуру, которая позволяет пользователям удалять строки, с которыми они хотят, но запрещать то, что вы хотите в соответствии с вашими собственными правилами. Затем запретите удаление доступа к таблице и разрешите выполнение доступа к sproc
  2. Добавьте вторичную таблицу со ссылками на внешний ключ, вызовите таблицу MasterAccounts или аналогичную, запретите доступ к этой таблице для обновления / удаления и добавьте ссылки на нее в соответствующие учетные записи, это предотвратит удаление учетной записи любым пользователем поскольку есть ссылка из этой таблицы на нее
  3. Добавить триггер, как OrbMan предлагает
  4. Добавьте представление, через которое они могут удалять строки, пропустите все те учетные записи, которые им запрещено удалять, запретьте доступ для удаления к основной таблице и разрешите удалить доступ к представлению

Сказав это, если ваши пользователи имеют достаточный доступ для общения с вашей базой данных через SQL, то вы действительно просто напрашиваетесь на неприятности. Вам следует усилить безопасность и разрешить доступ к базе данных только через ваше приложение и установленные протоколы. Тогда у вас есть много вариантов, чтобы избежать подобных проблем.

1 голос
/ 15 декабря 2008

Я использую следующий триггер:

CREATE TRIGGER [dbo].[mytable_trd] ON [dbo].[mytable]
WITH EXECUTE AS CALLER
INSTEAD OF DELETE
AS
BEGIN
SET NOCOUNT ON
DECLARE @tn varchar(255)
SELECT @tn = object_name(parent_obj)
FROM sysobjects
WHERE id = @@procid;

SET @tn = 'Deletes not allowed for this table: ' + @tn;
-- Add your code for checking the values from deleted
IF EXISTS(select * from deleted where mycolumn = 1)
  RAISERROR (@tn, 16, 1)    
END
GO
0 голосов
/ 15 декабря 2008

Я предпочитаю решение, использующее реляционную модель и ее правила целостности.

Для каждой записи в Tbl_Account, которую нельзя удалить, я бы добавил запись в Tbl_AccountMaster, где Tbl_Account.id_Account - это внешний ключ. Tbl_AccountMaster недоступен для обновления, кроме как администратором базы данных. Никто другой не сможет удалить записи из Tbl_Account, связанные с Tbl_AccountMaster.

РЕДАКТИРОВАТЬ: Я только что заметил, что была разработана та же идея здесь . Спасибо, Билл!

0 голосов
/ 14 декабря 2008

Вы уверены, что это правда, что вы никогда не захотите, чтобы кто-нибудь удалил эти строки? Даже ты или дба? Или работа по обслуживанию dbms?

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

0 голосов
/ 14 декабря 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...