Sql 在更新触发器中-获取不带列名的主键

Sql 在更新触发器中-获取不带列名的主键,sql,sql-server,sql-server-2008,triggers,Sql,Sql Server,Sql Server 2008,Triggers,我需要在不知道主键列名称的情况下更新DateModified列 基本上,我有一个简单的jane更新触发器,如下所示: CREATE TRIGGER updated_SCHEMA_TABLE ON [SCHEMA].[TABLE] AFTER UPDATE AS BEGIN SET NOCOUNT ON; UPDATE [SCHEMA].[TABLE] SET DateModified = getdate() WH

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

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

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
但不知道主键的列名,因为触发器将以编程方式生成


这可能吗?

好吧,我只是快速浏览了一些系统视图,没有看到任何东西告诉您每个表的主键是什么。您可能需要手工操作。

好吧,我只是快速浏览了一些系统视图,没有看到任何东西告诉您每个表的主键是什么。您可能需要手工操作。

好吧,也许我在上一个问题中留下这部分作为练习有点不公平

这适用于具有单列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

好吧,也许我有点不公平,在前面的问题中将这部分作为练习

这适用于具有单列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

如果您能够从标识列生成所有主键:

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。

如果您能够从标识列生成所有主键:

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表查看索引。如果PK有多个列,则触发器将不起作用。您可以使用EXISTS而不是IN。您可以使用INFORMATION\u SCHEMA.TABLE\u CONSTRAINTS视图和INFORMATION\u SCHEMA.KEY\u COLUMN\u USAGE视图获取PK列。如果PK有多个列,则触发器将不起作用。您可以使用EXISTS而不是IN。您可以使用INFORMATION\u SCHEMA.TABLE\u CONSTRAINTS视图和INFORMATION\u SCHEMA.KEY\u COLUMN\u USAGE视图获取PK列。它们清晰可见:从sys.objects中选择*,其中type='PK'aha!我知道它在某个地方,但我就是找不到。它们就在眼前:从sys.objects中选择*,其中type='PK'aha!我知道它在什么地方,就是找不到。实际上,这本可以像所有PK都是IsIdentity一样工作……但是Joe比你做得更好,他的代码就是我使用的。+1。事实上,这将工作以及所有的PKs是IsIdentity…但乔击败了你,他的代码是我用的。