【问题标题】:Find Identity columns from another database从另一个数据库中查找标识列
【发布时间】:2011-04-07 09:31:04
【问题描述】:

通常使用 SQL Server,您可以使用像这样的 COLUMNPROPERTY 函数来查找数据库中的标识列:

select TABLE_NAME + '.' + COLUMN_NAME, TABLE_NAME 
from INFORMATION_SCHEMA.COLUMNS 
where TABLE_SCHEMA = 'dbo' 
and COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 1 
order by TABLE_NAME 

但是当从另一个数据库运行查询时,我不知道如何让它工作。例如。这不会返回任何结果:

Use FirstDatabase
Go

select TABLE_NAME + '.' + COLUMN_NAME, TABLE_NAME 
from SecondDatabase.INFORMATION_SCHEMA.COLUMNS 
where TABLE_SCHEMA = 'dbo' 
and COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 1 
order by TABLE_NAME 

【问题讨论】:

    标签: sql-server identity sql-server-2008-r2 information-schema


    【解决方案1】:

    Object_ID 仅在当前数据库中有效,除非您使用 3 部分名称,但这种形式使用起来很复杂。此外,ColumnProperty 仅适用于当前数据库。

    select o.name + '.' + c.name, o.name
    from test1.sys.columns c
    join test1.sys.objects o on c.object_id = o.object_id
    join test1.sys.schemas s on s.schema_id = o.schema_id
    where s.name = 'dbo'
      and o.is_ms_shipped = 0 and o.type = 'U'
      and c.is_identity = 1
    order by o.name
    

    【讨论】:

    • 正确 - Object_id 似乎可以跨数据库工作,但 ColumnProperty 似乎不能。
    【解决方案2】:

    无法借助 COLUMNPROPERTY 从另一个数据库获取信息。但是有解决方法:

    DECLARE @DatabaseName VARCHAR(MAX)
    DECLARE @TableName VARCHAR(MAX)
    DECLARE @SQL VARCHAR(MAX)
    
    SET @DatabaseName = 'MyDatabase'
    SET @TableName = 'MyTable'
    
    SET @SQL = '
    SELECT 
        C.TABLE_NAME,
        C.COLUMN_NAME,
        S.IS_IDENTITY
    FROM ' + @DatabaseName + '.INFORMATION_SCHEMA.COLUMNS AS C
    LEFT JOIN ' + @DatabaseName + '.SYS.COLUMNS AS S ON OBJECT_ID(''' + @DatabaseName + '.dbo.' + @TableName + ''') = S.OBJECT_ID AND C.COLUMN_NAME = S.NAME
    WHERE S.IS_IDENTITY = 1'
    
    EXEC(@SQL)
    

    【讨论】:

    • 您的答案与接受的答案有何不同?连你都说不可能?
    • 是的,直接不可能。但是这段代码包含的解决方法可以完美地满足 topicstarter 的要求:从另一个数据库中的表中获取身份信息。
    • 我的 +1 是因为 INFORMATION_SCHEMA.COLUMNS 和 SYS.COLUMNS 的连接方式得到了结果。而接受的答案不使用 INFORMATION_SCHEMA.COLUMNS。就我而言,我不得不使用它。
    【解决方案3】:

    这对我使用特定的数据库有用:

    USE <database_name>;
    GO
    SELECT SCHEMA_NAME(schema_id) AS schema_name
        , t.name AS table_name
        , c.name AS column_name
    FROM sys.tables AS t
    JOIN sys.identity_columns c ON t.object_id = c.object_id
    ORDER BY schema_name, table_name;
    GO
    

    【讨论】:

      【解决方案4】:

      在此示例中,我在“Database1”中构建了一个存储过程,它使用动态 SQL 从“Database2”中的表中检索列信息(使用“Database2”中的 [INFORMATION_SCHEMA].[COLUMNS] 系统视图) ):

      ALTER PROCEDURE [Database1].[Schema1].[ColumnNames] @Database2 nvarchar(128), @Schema2 nvarchar(128), @Table2 nvarchar(128)
      AS
      
      BEGIN
          DECLARE @Sql nvarchar(1000)
      
          SET @Sql = 'SELECT [COLUMN_NAME], [ORDINAL_POSITION] FROM [' + @Database2 + '].[INFORMATION_SCHEMA].[COLUMNS]
                      WHERE [TABLE_SCHEMA] = ''' + @Schema2 + ''' AND [TABLE_NAME] = ''' + @Table2 + ''''
          EXEC(@Sql)
      END 
      

      【讨论】:

        【解决方案5】:

        我使用的是 SQL Server 2019,并且遇到了同样的挑战。我不确定此修复是否适用于旧版本,但每个数据库中都有一个名为 Your-DB-Name.sys.identity_columns 的视图。如果您从此视图中选择,您将看到您在该数据库中定义的标识列的列表。

        根据这些信息,您应该能够编写连接 YourDBName.Information_schema.columns 的连接,如下所示:

        选择 *
        FROM YourDBName.Information_Schema.columns col
        左外连接 YourDBName.sys.identity_columns idc
        ON idc.name = col.COLUMN_NAME AND idc.object_id = object_id('YourDBName..YourTableName')
        WHERE col.TABLE_NAME = 'YourTableName' AND col.table_catalog = 'YourDBName';

        YourDbName.sys.identity_columns 视图包含以下可能有用的字段:

        • object_id(用于连接回有问题的表,以防您有多个具有相同标识字段名称的表)
        • 名称(身份字段的名称)
        • column_id(表格中列的顺序)
        • is_identity(告诉您这是否是一个身份字段)
        • seed_value(身份字段的初始值)
        • increment_value(每次插入时标识字段增加多少)

        【讨论】:

          猜你喜欢
          • 2014-05-16
          • 2016-05-06
          • 2018-01-10
          • 2014-11-21
          • 2020-10-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多