【问题标题】:In an UPDATE trigger - get the Primary Key without the column's name在 UPDATE 触发器中 - 获取没有列名的主键
【发布时间】:2010-09-27 19:06:51
【问题描述】:

我需要在不知道主键列名称的情况下更新 DateModified 列。

基本上,我有一个简单的更新触发器,如下所示:

CREATE TRIGGER updated_SCHEMA_TABLE
 ON [SCHEMA].[TABLE]
   AFTER UPDATE AS 
     BEGIN 
       SET NOCOUNT ON; 
       UPDATE [SCHEMA].[TABLE] 
       SET DateModified = getdate() 
       WHERE [PRIMARYKEY]
       IN (SELECT [PRIMARYKEY]
       FROM Inserted)
     END

但不知道主键的列名,因为触发器将以编程方式生成 (see this question as to why)。

这可能吗?

【问题讨论】:

  • Y如果 PK 有多于一列,我们的触发器将不起作用。您可以使用 EXISTS() 代替 IN()。
  • 您可以使用INFORMATION_SCHEMA.TABLE_CONSTRAINTS 视图和INFORMATION_SCHEMA.KEY_COLUMN_USAGE 视图获取PK 列

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


【解决方案1】:

好吧,也许我在上一个问题中将此部分作为“练习”有点不公平。

这适用于具有单列 PK 的表。从这些开始,然后返回并使用复合 PK 手动调整这些可能是最简单的。

select 'create trigger updated_'+s.name + '_' + t.name + ' on  ' + quotename(s.name) + '.' + quotename(t.name) 
       + ' after update as'
       + ' begin '
       + ' set nocount on; '
       + ' update t'
       + '     set [DateModified] = getdate()'
       + '     from inserted i'
       + '         inner join ' + quotename(s.name) + '.' + quotename(t.name) + ' t'
       + '             on i.' + quotename(c2.name) + ' = t.' + quotename(c2.name)
       + ' end'
    from sys.columns c
        inner join sys.tables t
            on c.object_id = t.object_id
        inner join sys.schemas s
            on t.schema_id = s.schema_id
        inner join sys.indexes i
            on t.object_id = i.object_id
        inner join sys.index_columns ic
            on i.object_id = ic.object_id
                and i.index_id = ic.index_id
        inner join sys.columns c2
            on ic.object_id = c2.object_id
                and ic.index_id = c2.column_id
    where c.name = 'DateModified'
        and t.type = 'U'
        and i.is_primary_key = 1

【讨论】:

    【解决方案2】:

    如果您能够从身份列构建所有主键:

    SELECT table_name, column_name
    FROM INFORMATION_SCHEMA.COLUMNS
    where COLUMNPROPERTY (OBJECT_ID(Table_Name),Column_Name,'IsIdentity') = 1
     and table_schema = [SCHEMA] and table_name = [TABLE]
    

    否则,您将不得不使用所有 sys 表查看索引(干得好,Joe)。

    【讨论】:

    • +1。这实际上会像所有的 PK 都是 IsIdentity 一样有效......但乔打败了你,他的代码就是我使用的。
    【解决方案3】:

    好吧,我只是快速浏览了一些系统视图,但我没有看到任何信息告诉您每个表的主键是什么。您可能只需要手动完成。

    【讨论】:

    • 他们一目了然:select * from sys.objects where type = 'PK'
    • 啊哈!我知道它在某个地方,只是找不到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多