我正在尝试动态创建触发器,需要替换部分create语句,特别是连接完成的数据库名称。
CREATE TRIGGER [dbo].[tr_UseType_update] ON [dbo].[UseType] FOR UPDATE AS
BEGIN
SET NOCOUNT ON
INSERT [dbo].[UseType]
SELECT 'Updated', i.*
FROM inserted
INNER JOIN [(SELECT DB_NAME())].[dbo].[UseType] i ON inserted.[UseTypeID] = i.[UseTypeID]
END
我已经尝试过了,但很明显它只是使用了它实际上没有评估SELECT DB_NAME()的文本,有没有办法让它来评估这个值。
我正在使用sql 2005/8。我们有一个使用sqlcmd的部署工具,因此后备将更改工具以接收可传递给sqlcmd的变量,但是如果我可以减少工作量并在脚本本身(生成)中执行此操作很方便。
答案 0 :(得分:4)
唯一的方法是使用动态sql。
没有其他方法可以参数化数据库名称或表名。
话虽如此,动态创建这样的触发器似乎是一个危险的想法。
做你想做的最简单的方法就是:
USE MyDataBase
DECLARE @DB varchar(100) = 'MyOtherDatabaseThatIAmJoiningToInTheInsert'
DECLARE @SQL Varchar (MAX)
SET @SQL = '
CREATE TRIGGER [dbo].[tr_UseType_update] ON [dbo].[UseType] FOR UPDATE AS
BEGIN
SET NOCOUNT ON
INSERT [dbo].[UseType]
SELECT ''Updated'', i.*
FROM inserted
INNER JOIN ' + @DB + '.[dbo].[UseType] i ON inserted.[UseTypeID] = i.[UseTypeID]
END'
It's mandatory to read this before doing any dynamic sql code, though!
答案 1 :(得分:0)
您可能会执行动态sql并将其加载到临时表中,而临时表又可用于触发器。
CREATE TRIGGER [dbo].[tr_UseType_update] ON [dbo].[UseType]
FOR UPDATE
AS
BEGIN
SET NOCOUNT ON
CREATE TABLE #t (userTypeId INT)
DECLARE @sql NVARCHAR(500) SET @sql = 'insert into #t select userTypeID from ' + DB_NAME() + '.dbo.UseType'
EXEC sp_executeSQL @sql
INSERT [dbo].[UseType]
SELECT 'Updated',
i.*
FROM inserted
INNER JOIN #t i ON inserted.[UseTypeID] = i.[UseTypeID]
END