MS SQL查询中的表名变量

时间:2016-10-05 07:25:53

标签: sql sql-server tsql variables triggers

我已经动态创建了表格,例如XXX_JOURNAL。 其中XXX - 是表前缀(变量),_JOURNAL - 在表名中是常量。

我需要在数据库上创建UPDATE触发器,而不是在特定表上,并使用表名(前缀)作为变量:

CREATE TRIGGER triggerName ON %_JOURNAL
FOR UPDATE
AS
UPDATE XXX_JOURNAL
SET COMPANY_ID = LEFT(tableName,3) //tableName = current table (XXX_JOURNAL)
WHERE ID = ID FROM inserted

所以这里有两个困难:

  1. 如何为所有表LIKE %_JOURNAL创建一个触发器?
  2. 如何使用表名作为当前表的关键字?
  3. 我知道语法上有很多错误。例如,我不能在创建触发器时使用'%_JOURNAL'作为表名。它只是为了解释,我需要在将来为所有动态创建的表创建一个触发器。

    有什么想法吗?

1 个答案:

答案 0 :(得分:0)

您可以将存储过程与动态SQL一起使用:

CREATE PROCEDURE TriggerCreationForJournals
    @XXX as nvarchar(3)
AS
BEGIN

    DECLARE @sql nvarchar(max),
            @triggerName nvarchar(max) = @XXX + N'_JOURNAL_UPDATE',
            @objectCheck int,
            @checkSQL nvarchar(max),
            @params nvarchar(max) = N'@objectCheck int OUTPUT' 

    SELECT @checkSQL = N'SELECT @objectCheck = OBJECT_ID(N'''+@triggerName+''')'

    EXEC sp_executesql @checkSQL, @params, @objectCheck = @objectCheck OUTPUT

    IF @objectCheck IS NULL
    BEGIN
        SELECT @sql = N'
        CREATE TRIGGER '+QUOTENAME(@triggerName)+' ON ['+@XXX+'_JOURNAL]
        FOR UPDATE
        AS
        UPDATE x
        SET COMPANY_ID = '''+@XXX+'''
        FROM ['+@XXX+'_JOURNAL] x
        INNER JOIN inserted i
            ON i.ID = x.ID'

        EXEC sp_executesql @sql
    END
    ELSE
    BEGIN
        PRINT 'Trigger '+QUOTENAME(@triggerName)+' already exists'
    END
END

然后运行:

DECLARE @sql nvarchar(max)

SELECT @sql = (
    SELECT 'EXEC TriggerCreationForJournals '''+LEFT([name],3) +''';' +CHAR(10)
    FROM sys.tables 
    WHERE [name] LIKE '%JOURNAL'
    FOR XML PATH('')
)

EXEC sp_executesql @sql

为所有表创建触发器。

@sql中会有如下查询:

EXEC TriggerCreationForJournals 'AFG';
EXEC TriggerCreationForJournals 'DFG';

存储过程的目的是检查表上是否存在触发器 - 如果是,则跳过它的创建,如果存在则可以修改SP以删除它们。

第二部分是创建脚本并为所需的所有表运行SP。

希望,这个答案可以帮助您解决问题。