1

当用户想要向表中插入数据时,我想动态创建文件组,但 SQL Server 抛出异常。

我知道我可以使用 SQL Server 代理来处理这个问题,但如果我的方法不正确,请告诉我正确的方法。

亲切的问候。

ALTER TRIGGER [AuditTrigger]
ON [Audit]
INSTEAD OF INSERT
AS
BEGIN
    DECLARE @DateInserted DATETIME = (SELECT DateInserted FROM inserted);
    DECLARE @NextRange DATETIME;

    DECLARE @currentFileGroup NVARCHAR(MAX)= ('APP_PT_' + CAST(YEAR(@DateInserted) AS NVARCHAR(4)) +'_'+ CAST(MONTH(@DateInserted) AS NVARCHAR(2)))
    --print @currentFileGroup;

    DECLARE @fileExsits BIT = (SELECT (CASE WHEN EXISTS(SELECT NULL AS [EMPTY]  FROM SYS.FILEGROUPS WHERE name  LIKE  @currentFileGroup) THEN 1  ELSE 0  END))

    IF @fileExsits = 0
    BEGIN 
        SET @NextRange = (SELECT Replace(CONVERT(VARCHAR(10), @DateInserted, 111),'/','-'))

        DECLARE @filefullname VARCHAR(MAX) = (SELECT physical_name FROM SYS.DATABASE_FILES WHERE name = 'DB_Test')
        DECLARE @fgFullName  VARCHAR(MAX) = (SELECT (LEFT(@filefullname, LEN(@filefullname) - CHARINDEX('\', REVERSE(@filefullname))) + '.ndf'))

        -- The exception occurs here --
        ALTER DATABASE DB_TEST 
        ADD FILE (NAME = [@currentFileGroup],
                  FILENAME = [@fgFullName],
                  SIZE = 5MB,
                  MAXSIZE = 100MB,
                  FILEGROWTH = 1MB)
        TO FILEGROUP Audit_2017

        ALTER PARTITION FUNCTION  [PF]() 
        SPLIT RANGE (@NextRange);

        ALTER PARTITION SCHEME [PS]  
        NEXT USED [@currentFileGroup];
    END

    INSERT INTO LogTable VALUES (@currentFileGroup)

    INSERT INTO [Audit] 
        SELECT DateInserted, Title 
        FROM inserted;
END

结果:

消息 287,级别 16,状态 2,过程 AuditTrigger,第 24 行
触发器中不允许使用 ALTER DATABASE 语句。

4

1 回答 1

2

除了触发器,您可以使用存储过程来插入审计表,并在其中包含文件组/文件/分区维护代码。请注意,由于子查询,此触发器将在多行插入时失败。

也就是说,我认为分区维护的计划日常工作方法更清洁。不知道你为什么要为每个分区创建一个新文件和文件组。除非您有特殊用例,否则您可以简单地将每个分区放在同一个文件组上。确保分区功能是RANGE RIGHT为了避免在SPLIT.

于 2017-12-17T13:19:48.650 回答