【问题标题】:SQL - Using a Trigger to occasionally allow row deletionsSQL - 使用触发器偶尔允许删除行
【发布时间】:2018-10-02 15:40:06
【问题描述】:

我有一些正在使用的视图,如果数据表被另一个表中的变量锁定,我需要设置一个触发器来防止删除视图中的任何数据。我已经设置了触发器,并且使用“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

我确定有一些愚蠢的逻辑陈述或我遗漏的东西,但我会感谢我能得到的所有帮助。谢谢!

【问题讨论】:

  • 触发器是高度特定于供应商的 - 所以请添加一个标签来指定您使用的是mysqlpostgresqlsql-serveroracle 还是db2 - 或完全不同的东西。
  • 我正在使用 sql-server,将更新主帖。感谢您的信息。
  • 您不能从视图中删除数据 - 您需要直接从基础表中删除它
  • 对,但是我可以通过视图删除数据,对吧?我刚试了一下,看来可以了……我应该更新主帖来澄清一下吗?

标签: sql sql-server triggers sql-delete


【解决方案1】:

您不能直接从视图中删除 - 您需要从基础表中删除。

所以基本上,您需要为您的表添加一个(或多个)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

【讨论】:

  • 好的,只是为了澄清一下,Deleted 表是否会包含在原始删除查询通过时会被删除的值?
  • 好的,所以每当我尝试这个时,我都会收到一条错误消息,提示“Deleted.FirstPrimaryKeyColumn”无法绑定。
  • @AlpheausFeltham:是的,Deleted 将包含您视图中的所有行,这些行将被删除。当然,您需要调整我的代码以使用 YOUR 列名!您没有发布视图/表结构,所以我无法知道您的列名是什么 - 它只是指第一个表的 主键列 - 用该列替换它被称为
【解决方案2】:

也许“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

【讨论】:

  • 这是我最初的想法,但视图只允许'INSTEAD OF'
  • 那是个混蛋:(
猜你喜欢
  • 1970-01-01
  • 2020-07-20
  • 1970-01-01
  • 2021-11-24
  • 1970-01-01
  • 2019-04-17
  • 1970-01-01
  • 1970-01-01
  • 2017-08-28
相关资源
最近更新 更多