MSSQL 中的 INSERT 触发器:按变量的目标表
Posted
技术标签:
【中文标题】MSSQL 中的 INSERT 触发器:按变量的目标表【英文标题】:INSERT Trigger in MSSQL: destination table by Variable 【发布时间】:2014-09-18 09:19:13 【问题描述】:多个程序/进程将它们的历史记录插入一个(非常大的)历史记录表 (tbl_History)。我无法改变这一点。我必须在插入时将它们分类到“正确的”历史表中。这些不同的历史表确实已经存在。那我就不创作了。但是通过参数“his_ID”我可以检查,女巫表是正确的目标表。
所以我在这个表中添加了一个触发器。这个有效:
CREATE TRIGGER [dbo].[Trigger_tbl_History_Insert]
ON [dbo].[tbl_History]
AFTER INSERT
AS
BEGIN
INSERT INTO [tbl_Historyef33894e-3fda-4833-b1e6-efa5cb9ce8ee] SELECT * FROM inserted;
END
但现在我想通过新插入行中的变量来决定目标表。我是这么想的:
CREATE TRIGGER [dbo].[Trigger_tbl_History_Insert]
ON [dbo].[tbl_History]
AFTER INSERT
AS
BEGIN
DECLARE @hisID varchar(max);
SELECT @hisID = inserted.his_ID FROM inserted;
INSERT INTO [tbl_History + @hisID ] SELECT * FROM inserted;
END
显然它不是这样工作的。 :-) 有没有办法做到这一点?
以下方法不能完全正确地工作:
CREATE TRIGGER [dbo].[Trigger_tbl_History_Insert]
ON [dbo].[tbl_History]
AFTER INSERT
AS
BEGIN
DECLARE @hisID varchar(max);
SELECT @hisID = inserted.his_ID FROM inserted;
EXEC ('INSERT INTO tbl_History' + @hisID + ' SELECT * FROM inserted');
END
创建错误:“'-' 附近的语法不正确”
CREATE TRIGGER [dbo].[Trigger_tbl_History_Insert]
ON [dbo].[tbl_History]
AFTER INSERT
AS
BEGIN
DECLARE @hisID varchar(max);
SELECT @hisID = inserted.his_ID FROM inserted;
EXEC ('INSERT INTO [tbl_History' + @hisID + '] SELECT * FROM inserted');
END
创建错误:“无效的对象名称'插入'。”
【问题讨论】:
你的意思是在每次插入后你想将数据保存到 [tbl_History + @hisID ] 对吗??如果您的回答是肯定的,那么这意味着在每次插入时它都会根据 id 创建新表并保存数据!!! 我不确定你是否可以使用,但将Insert
放入动态代码中......
首先是,然后不是。 ;-) 它不会创建新表。该表确实已经存在。几个程序/进程将它们的历史插入到一个单一的历史表中。我无法改变这一点。我必须在插入时将它们分类到“正确的”历史表中。我现在会在帖子中添加这个解释。
@Tagamoga:你的意思是说 [tbl_History123] 已经创建或存在。您只需要通过正确的触发器将数据插入其中???。这里 123 是您的 @hisID。
是的,没错。 @hisID 由插入的.his_ID 填充
【参考方案1】:
好吧,在这里我假设名为 [tbl_History123] 的表将存在,其中 123 是变量 @hisID。所以在这种情况下,你可以这样做 -
CREATE TRIGGER [dbo].[Trigger_tbl_History_Insert]
ON [dbo].[tbl_History]
AFTER INSERT
AS
BEGIN
DECLARE @hisID varchar(max);
SELECT @hisID = inserted.his_ID FROM inserted;
EXEC ('INSERT INTO tbl_History' + @hisID + ' SELECT * FROM inserted');
-- OR you can also do this
EXEC (
'SELECT *
INTO tbl_History' + @hisID + '
FROM inserted'
);
END
已编辑
好的,创建另一个单独的表 - tmpHistoryForID 与您的 [tbl_History123] 具有相同的架构。这用作中介表。所以在触发器中首先将数据插入到这个表中,然后从这个表中插入到你的 [tbl_History123] 表中。像这样-
CREATE TRIGGER [dbo].[Trigger_tbl_History_Insert]
ON [dbo].[tbl_History]
AFTER INSERT
AS
BEGIN
DECLARE @hisID varchar(max);
SELECT @hisID = inserted.his_ID FROM inserted;
INSERT INTO dbo.tmpHistoryForID
SELECT * FROM inserted
EXEC ('INSERT INTO tbl_History' + @hisID + ' SELECT * FROM dbo.tmpHistoryForID');
TRUNCATE TABLE dbo.tmpHistoryForID
END
【讨论】:
非常感谢您的帮助,但仍然没有运行。不幸发生以下错误:“'-' 附近的语法不正确。”当我将 EXEC 行更改为 'EXEC ('INSERT INTO [tbl_History' + @hisID + '] SELECT * FROM inserted');'它告诉我:“无效的对象名称'插入'。”我也会将其添加到帖子中...EXEC
或 EXECUTE
语句用于实现 SQL Server 在第一次解析时不允许的操作。实际上,SQL Server 会解析您的指令并检查是否有任何错误。因为您的表tblHistory + @hisID
不存在,即[tblHistory + @hidID]
,所以它不允许您使用。因此,使用EXEC
或EXECUTE
命令将解析与“运行时”不同。
表格确实存在。否则“插入 [tbl_Historyef33894e-3fda-4833-b1e6-efa5cb9ce8ee] SELECT * FROM 插入;”不会工作。
@Tagamoga:我已经更新了我的答案。查看编辑部分
我爱你!但请在您的语句中添加“[]”,因为 MSSQL 不喜欢表名 bg 中的“-”:“EXEC ('INSERT INTO [tbl_History' + @userID + '] SELECT * FROM dbo. tbl_tmpHistoryForID');"【参考方案2】:
您无法使用动态 SQL 查询访问魔术表。在执行动态查询之前,将记录放入临时表中。下面是触发器的代码。
CREATE TRIGGER [dbo].[Trigger_tbl_History_Insert]
ON [dbo].[tbl_History]
AFTER INSERT
AS
BEGIN
DECLARE @ID int;
DECLARE @Qry varchar(max)
SELECT @ID = inserted.ID FROM inserted;
select * into #tmp from inserted
SET @Qry=CONCAT('INSERT INTO tbl_History' , @ID ,' SELECT * FROM #tmp')
EXEC (@Qry)
END
【讨论】:
以上是关于MSSQL 中的 INSERT 触发器:按变量的目标表的主要内容,如果未能解决你的问题,请参考以下文章