SQL Server 2008:在db中的所有表中创建触发器

时间:2013-04-26 15:51:10

标签: sql sql-server sql-server-2008 tsql triggers

使用SQL Server 2008,我创建了一个数据库,其中每个表都有一个名为“CreatedDt”的日期时间列。我想要做的是为每个表创建一个触发器,以便在插入值时,使用当前日期和时间填充CreatedDt列。

如果你原谅我的伪代码,那么我所追求的就是T-SQL的等价物:

foreach (Table in MyDatabase)
{
   create trigger CreatedDtTrigger
   {
        on insert createddt = datetime.now;
   }
}

如果有人愿意帮忙,我会非常感激。谢谢!

3 个答案:

答案 0 :(得分:2)

正如@EricZ所说,最好的办法是绑定列的默认值。以下是使用游标和动态SQL将其添加到每个表的方法:

当然,您可以使用光标:

declare @table sysname, @cmd nvarchar(max)
declare c cursor for
  select name from sys.tables where is_ms_shipped = 0 order by name
open c; fetch next from c into @table
while @@fetch_status = 0
begin
  set @cmd = 'ALTER TABLE ' + @table + ' ADD CONSTRAINT DF_' + @table + '_CreateDt DEFAULT GETDATE() FOR CreateDt'
  exec sp_executesql @cmd
  fetch next from c into @table
end
close c; deallocate c

答案 1 :(得分:2)

无需前往Cursors。只需复制QueryExecute下面的结果

select distinct 'ALTER TABLE '+ t.name + 
' ADD CONSTRAINT DF_'+t.name+'_crdt DEFAULT getdate() FOR '+ c.name
from sys.tables t
inner join sys.columns c on t.object_id=c.object_id
where c.name like '%your column name%'

答案 2 :(得分:1)

这是另一种方法:

DECLARE @SQL nvarchar(max);
SELECT @SQL = Coalesce(@SQL + '
', '')
    + 'ALTER TABLE ' + QuoteName(T.TABLE_SCHEMA) + '.' + QuoteName(T.TABLE_NAME)
    + ' ADD CONSTRAINT ' + QuoteName('DF_'
    + CASE WHEN T.TABLE_SCHEMA <> 'dbo' THEN T.Table_Schema + '_' ELSE '' END
    + C.COLUMN_NAME) + ' DEFAULT (GetDate()) FOR ' + QuoteName(C.COLUMN_NAME)
    + ';'
FROM
   INFORMATION_SCHEMA.TABLES T
   INNER JOIN INFORMATION_SCHEMA.COLUMNS C
      ON T.TABLE_SCHEMA = C.TABLE_SCHEMA
      AND T.TABLE_NAME = C.TABLE_NAME
WHERE
   C.COLUMN_NAME = 'CreatedDt'
;
EXEC (@SQL);

这会产生并运行一系列类似于以下内容的语句:

ALTER TABLE [schema].[TableName] -- (line break added)
   ADD CONSTRAINT [DF_schema_TableName] DEFAULT (GetDate()) FOR [ColumnName];

一些注意事项:

  • 这会使用INFORMATION_SCHEMA次观看。最好的做法是在可能的情况下使用这些而不是系统表,因为它们保证不会在SQL Server版本之间进行更改(而且在许多DBMS上都受支持,因此在所有条件相同的情况下,最好使用符合标准的/可移植的代码)。

  • 在具有区分大小写的默认排序规则的数据库中,必须使用大写字母表示INFORMATION_SCHEMA视图名称和列名称。

  • 创建脚本时,重要的是要注意模式名称和正确的转义(使用QuoteName)。如果不这样做,有一天打破 某人的系统。

  • 我认为最好将DEFAULT表达式放在括号内。虽然在这种情况下没有收到任何错误,但如果函数GetDate()被参数化和/或更改为更复杂的表达式,则不会有任何错误。

如果您认为列默认值不适合您,那么您仍可以使用您想象的触发器。但是,管理触发器是否已经存在并且适当地更改或创建它需要一些认真的工作,加入触发器内的inserted元表,并根据主键列的完整列表进行操作。表(如果它们存在,如果它们不存在,那么你就不幸了)。这很可能,但非常困难 - 你最终可能会使用嵌套的,嵌套的,嵌套的动态SQL。我有这样的自动化对象创建脚本,连续包含13个引号......