是否可以防止在没有 WHERE 子句的情况下执行 UPDATE 或 DELETE 语句?

Mat*_*t W 7 t-sql sql-server sql-server-2008

正如标题所暗示的,如果 UPDATE 和 DELETE 语句没有 WHERE 子句,我们希望防止在特定的 SQL Server(2008 或更高版本)数据库或表上执行 - 至少通过手动接口。

那可能吗?

Eri*_*ndt 5

你可以。这并不理想,但您可以创建表触发器来评估每个触发器UPDATEDELETE确定它们将影响多少行。

Erik Darling 在Brent Ozar 的博客上发表了关于它的博客。他和我都不一定会推荐它,但如果情况足够绝望,那么这会奏效。

这是链接中的相关代码,以防万一,你知道,布伦特关闭了商店。他很浮躁。

CREATE OR ALTER TRIGGER dbo.UseAWhereClauseNextTime
ON dbo.TriggerTest
FOR UPDATE, DELETE
AS
    BEGIN

        DECLARE @rc INT = @@ROWCOUNT;
        DECLARE @table_rows INT = (   SELECT row_count
                                      FROM   sys.dm_db_partition_stats
                                      WHERE  object_id = OBJECT_ID('dbo.TriggerTest')
                                             AND index_id IN ( 0, 1 ));

        IF EXISTS ( SELECT 1 FROM Inserted ) AND EXISTS ( SELECT 1 FROM Deleted )
            BEGIN
                IF (( @rc * 100 ) / ( @table_rows )) >= 98
                    BEGIN
                        RAISERROR('USE A WHERE CLAUSE DUMMY', 0, 1) WITH NOWAIT;
                        ROLLBACK;
                    END;
            END;

        IF NOT EXISTS ( SELECT 1 FROM Inserted ) AND EXISTS ( SELECT 1 FROM Deleted )
            IF (   ( @table_rows = 0 )
                   OR (   @table_rows > 0
                          AND (( @rc * 100 ) / ( @table_rows + @rc )) >= 98 ))
                BEGIN
                    RAISERROR('USE A WHERE CLAUSE DUMMY', 0, 1) WITH NOWAIT;
                    ROLLBACK;
                END;

    END;

GO
Run Code Online (Sandbox Code Playgroud)

这两个子句(( @rc * 100 ) / ( @table_rows )) >= 98将“坏”语句的阈值设置为受影响表的 98%,Erik 指出这有点随意,但也是可配置的。