Sql server 从另一个数据库中查找标识列

Sql server 从另一个数据库中查找标识列,sql-server,identity,sql-server-2008-r2,information-schema,Sql Server,Identity,Sql Server 2008 R2,Information Schema,通常,对于SQL Server,您可以使用如下功能来查找数据库中的标识列: 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

通常,对于SQL Server,您可以使用如下功能来查找数据库中的标识列:

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 <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
但是,当从另一个数据库运行查询时,我不知道如何使其工作。例如,这不会返回任何结果:

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 

除非使用由三部分组成的名称,否则Object_ID仅在当前数据库中有效,但该表单使用起来很复杂。此外,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

这在我使用特定数据库时起到了作用:

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 <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
使用;
去
选择SCHEMA_NAME(SCHEMA_id)作为SCHEMA_NAME
,t.name作为表名称
,c.name作为列名称
从sys.tables作为t
在t.object\u id=c.object\u id上连接sys.identity\u列c
按模式名称、表名称排序;
去

无法借助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)

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


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

根据这些信息,您应该能够编写一个连接YourDBName.information\u schema.columns的联接,如下所示:

选择*
从YourDBName.Information\u Schema.columns coll
左外连接YourDBName.sys.identity\u列idc
在idc.name=col.COLUMN\u name和idc.object\u id=object\u id('YourDBName..YourTableName')上
其中col.TABLE_NAME='YourTableName'和col.TABLE_catalog='YourDBName'

YourDbName.sys.identity\u列视图包含以下可能有用的字段:

  • 对象\u id(如果有多个表具有相同的标识字段名,则用于连接回相关表)
  • 名称(标识字段的名称)
  • 列\u id(表中列的顺序)
  • 是_identity(告诉您这是否是一个identity字段)
  • 种子值(标识字段的初始值)
  • 增量_值(每次插入时标识字段的升幅)

右-对象id在跨数据库中似乎有效,但ColumnProperty似乎无效。您的答案与公认的答案有何不同?即使你说这是不可能的?是的,这是不可能的。但这段代码包含的解决方法完全符合topicstarter的要求:从另一个DB.My+1中的表中获取标识信息,因为信息\u SCHEMA.COLUMNS和SYS.COLUMNS是通过连接来获得结果的。然而,接受的答案不使用信息_SCHEMA.COLUMNS。在我的情况下,我不得不使用这个。