SQL - Использование триггера для периодического разрешения удаления строк - PullRequest
0 голосов
/ 02 октября 2018

У меня есть несколько представлений, с которыми я работаю, и мне нужно настроить триггер, чтобы предотвратить удаление любых данных в представлении, если таблица данных заблокирована переменной в другой таблице.У меня уже есть настроенный триггер, и у меня нет проблем с настройкой замены команды удаления с помощью триггера «INSTEAD OF DELETE», но теперь моя проблема заключается в том, как сохранить входящий запрос на удаление для случаев, когда удаления разрешеноВ этом случае я использую SQL Server.

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

Код:

CREATE TRIGGER [database_name].[trigger_name]
ON [database_name].[view_name]
INSTEAD OF DELETE
AS
BEGIN
    SET NOCOUNT ON

    IF NOT EXISTS (SELECT * FROM [database_name].[control_table_name]
                   WHERE Control_Item = 'view_name' AND Can_modify = 'N')
    BEGIN
        SET NOCOUNT OFF
        --NEW DELETION STATEMENT GOES HERE, NEEDS TO BE DUPLICATE OF REPLACED DELETE QUERY--
    END
    ELSE
    BEGIN
        RAISEERROR('Deletions are currently disabled!', 11, 1);
    END
END

Я уверен, что есть какое-то глупое логическое утверждение или что-то, чего мне не хватает, но я буду признателен за любую помощь, которую смогу получить.Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Вы не можете удалить из представления напрямую - вам нужно удалить из базовой таблицы (таблиц).

Таким образом, вам нужно добавить один (или несколько) операторов DELETE для ваших таблиц - и, надеюсь, вы включили первичные ключи из всех базовых таблиц в ваше представление!

CREATE TRIGGER [database_name].[trigger_name]
ON [database_name].[view_name]
INSTEAD OF DELETE
AS
BEGIN
    SET NOCOUNT ON

    IF NOT EXISTS (SELECT * FROM [database_name].[control_table_name]
                   WHERE Control_Item = 'view_name' AND Can_modify = 'N')
    BEGIN
        SET NOCOUNT OFF

        DELETE FROM dbo.YourFirstTable
        WHERE PrimaryKeyColumn IN (SELECT FirstPrimaryKeyColumn FROM Deleted);

        -- if the view is built on top of several tables, you possibly need multiple DELETE statements here
        DELETE FROM dbo.YourSecondTable
        WHERE PrimaryKeyColumn IN (SELECT SecondPrimaryKeyColumn FROM Deleted);
    END
    ELSE
    BEGIN
        RAISEERROR('Deletions are currently disabled!', 11, 1);
    END
END
0 голосов
/ 02 октября 2018

Возможно, «FOR DELETE» может сделать трюк и сделать откат, когда удаление не разрешено.

CREATE TRIGGER [database_name].[trigger_name] 
ON [database_name].[view_name]
FOR DELETE
AS
    SET NOCOUNT ON

    IF EXISTS (SELECT * 
               FROM [database_name].[control_table_name]
               WHERE Control_Item = 'view_name' AND Can_modify = 'N')
    BEGIN
        RAISEERROR('Deletions are currently disabled!', 11, 1) WITH NOWAIT
        ROLLBACK
    END

    SET NOCOUNT OFF
GO
...