触发器中不允许使用 ALTER DATABASE 语句
The ALTER DATABASE statement is not allowed within a trigger
我想在用户想要将数据插入 table 时动态创建文件组,但是 SQL 服务器抛出异常。
我知道我可以使用 SQL Server Agent 来处理这个问题,但是如果我的方法不正确,请告诉我正确的方法。
亲切的问候。
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
结果:
Msg 287, Level 16, State 2, Procedure AuditTrigger, Line 24
The ALTER DATABASE statement is not allowed within a trigger.
您可以为审计 table 插入使用存储过程,并在其中包含 filegroup/file/partition 维护代码,而不是触发器。请注意,由于子查询,此触发器将在多行插入时失败。
也就是说,我认为分区维护的计划每日作业方法更干净。不确定您为什么要为每个分区创建一个新文件和文件组。除非您有特殊用例,否则您可以简单地将每个分区放在同一个文件组中。确保分区函数为 RANGE RIGHT
以避免在 SPLIT
.
期间进行过多的数据移动和日志记录
我想在用户想要将数据插入 table 时动态创建文件组,但是 SQL 服务器抛出异常。
我知道我可以使用 SQL Server Agent 来处理这个问题,但是如果我的方法不正确,请告诉我正确的方法。
亲切的问候。
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
结果:
Msg 287, Level 16, State 2, Procedure AuditTrigger, Line 24
The ALTER DATABASE statement is not allowed within a trigger.
您可以为审计 table 插入使用存储过程,并在其中包含 filegroup/file/partition 维护代码,而不是触发器。请注意,由于子查询,此触发器将在多行插入时失败。
也就是说,我认为分区维护的计划每日作业方法更干净。不确定您为什么要为每个分区创建一个新文件和文件组。除非您有特殊用例,否则您可以简单地将每个分区放在同一个文件组中。确保分区函数为 RANGE RIGHT
以避免在 SPLIT
.