关于sql server:如何确定以编程方式确定哪些SQL表具有Identity列

关于sql server:如何确定以编程方式确定哪些SQL表具有Identity列

How do you determine what SQL Tables have an identity column programmatically

我想在SQL Server 2005中创建一个列列表,这些列在T-SQL中具有标识列及其对应的表。

结果将类似于:

表名,列名


对于SQL Server而言,这样做的另一种可能的方法是使用
INFORMATION_SCHEMA观看次数:

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

sys.columns.is_identity = 1

例如

1
2
3
select o.name, c.name
from sys.objects o inner join sys.columns c on o.object_id = c.object_id
where c.is_identity = 1

另一种方式(对于2000 / 2005/2012/2014):

1
2
3
4
IF ((SELECT OBJECTPROPERTY( OBJECT_ID(N'table_name_here'), 'TableHasIdentity')) = 1)
    PRINT 'Yes'
ELSE
    PRINT 'No'

注意:table_name_here应该为schema.table,除非架构为dbo


在SQL 2005中:

1
2
3
select object_name(object_id), name
from sys.columns
where is_identity = 1

此查询似乎可以解决问题:

1
2
3
4
5
6
7
8
9
SELECT
    sys.objects.name AS table_name,
    sys.columns.name AS column_name
FROM sys.columns JOIN sys.objects
    ON sys.columns.object_id=sys.objects.object_id
WHERE
    sys.columns.is_identity=1
    AND
    sys.objects.type in (N'U')

以下查询对我有用:

1
2
3
4
select  TABLE_NAME tabla,COLUMN_NAME columna
from    INFORMATION_SCHEMA.COLUMNS
where   COLUMNPROPERTY(object_id(TABLE_SCHEMA+'.'+TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 1
order by TABLE_NAME

基于吉列尔莫答案的不带身份列的表列表:

1
2
3
4
SELECT DISTINCT TABLE_NAME
FROM            INFORMATION_SCHEMA.COLUMNS
WHERE        (TABLE_SCHEMA = 'dbo') AND (OBJECTPROPERTY(OBJECT_ID(TABLE_NAME), 'TableHasIdentity') = 0)
ORDER BY TABLE_NAME

这是适用于MSSQL 2000的工作版本。我修改了此处找到的2005代码:http://sqlfool.com/2011/01/identity-columns-are-you-nearing-the-limits/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/* Define how close we are to the value limit
   before we start throwing up the red flag.
   The higher the value, the closer to the limit. */

DECLARE @threshold DECIMAL(3,2);
SET @threshold = .85;

/* Create a temp table */
CREATE TABLE #identityStatus
(
      database_name     VARCHAR(128)
    , table_name        VARCHAR(128)
    , column_name       VARCHAR(128)
    , data_type         VARCHAR(128)
    , last_value        BIGINT
    , max_value         BIGINT
);

DECLARE @dbname sysname;
DECLARE @sql nvarchar(4000);

-- Use an cursor to iterate through the databases since in 2000 there's no sp_MSForEachDB command...

DECLARE c cursor FAST_FORWARD FOR
SELECT
    name
FROM
    master.dbo.sysdatabases
WHERE
    name NOT IN('master', 'model', 'msdb', 'tempdb');

OPEN c;

FETCH NEXT FROM c INTO @dbname;

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @sql = N'Use [' + @dbname + '];
    Insert Into #identityStatus
    Select '
'' + @dbname + ''' As [database_name]
        , Object_Name(id.id) As [table_name]
        , id.name As [column_name]
        , t.name As [data_type]
        , IDENT_CURRENT(Object_Name(id.id)) As [last_value]
        , Case
            When t.name = '
'tinyint''   Then 255
            When t.name = '
'smallint''  Then 32767
            When t.name = '
'int''       Then 2147483647
            When t.name = '
'bigint''    Then 9223372036854775807
          End As [max_value]
    From
        syscolumns As id
        Join systypes As t On id.xtype = t.xtype
    Where
        id.colstat&1 = 1    -- this identifies the identity columns (as far as I know)
    '
;

    EXECUTE sp_executesql @sql;

    FETCH NEXT FROM c INTO @dbname;
END

CLOSE c;
DEALLOCATE c;

/* Retrieve our results and format it all prettily */
SELECT database_name
    , table_name
    , column_name
    , data_type
    , last_value
    , CASE
        WHEN last_value < 0 THEN 100
        ELSE (1 - CAST(last_value AS FLOAT(4)) / max_value) * 100
      END AS [percentLeft]
    , CASE
        WHEN CAST(last_value AS FLOAT(4)) / max_value >= @threshold
            THEN 'warning: approaching max limit'
        ELSE 'okay'
        END AS [id_status]
FROM #identityStatus
ORDER BY percentLeft;

/* Clean up after ourselves */
DROP TABLE #identityStatus;

由于某种原因,sql server在不同的表中保存了一些标识列,因此对我有用的代码如下:

1
2
3
4
5
6
7
8
select      TABLE_NAME tabla,COLUMN_NAME columna
from        INFORMATION_SCHEMA.COLUMNS
where       COLUMNPROPERTY(object_id(TABLE_SCHEMA+'.'+TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 1
union all
select      o.name tabla, c.name columna
from        sys.objects o
inner join  sys.columns c on o.object_id = c.object_id
where       c.is_identity = 1

这适用于SQL Server 2005、2008和2012。
我发现sys.identity_columns并不包含我所有带有标识列的表。

1
2
3
4
5
6
SELECT a.name AS TableName, b.name AS IdentityColumn
FROM sys.sysobjects a
JOIN sys.syscolumns b
ON a.id = b.id
WHERE is_identity = 1
ORDER BY name;

在文档页面上,状态栏也可以使用。您还可以添加四个部分的标识符,它可以在不同的服务器上运行。

1
2
3
4
5
6
SELECT a.name AS TableName, b.name AS IdentityColumn
FROM [YOUR_SERVER_NAME].[YOUR_DB_NAME].sys.sysobjects a
JOIN [YOUR_SERVER_NAME].[YOUR_DB_NAME].sys.syscolumns b
ON a.id = b.id
WHERE is_identity = 1
ORDER BY name;

来源:
https://msdn.microsoft.com/zh-CN/library/ms186816.aspx


使用此:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DECLARE @Table_Name VARCHAR(100)
DECLARE @Column_Name VARCHAR(100)
SET @Table_Name = ''
SET @Column_Name = ''

SELECT  RowNumber = ROW_NUMBER() OVER ( PARTITION BY T.[Name] ORDER BY T.[Name], C.column_id ) ,
    SCHEMA_NAME(T.schema_id) AS SchemaName ,
    T.[Name] AS Table_Name ,
    C.[Name] AS Field_Name ,
    sysType.name ,
    C.max_length ,
    C.is_nullable ,
    C.is_identity ,
    C.scale ,
    C.precision
FROM    Sys.Tables AS T
    LEFT JOIN Sys.Columns AS C ON ( T.[Object_Id] = C.[Object_Id] )
    LEFT JOIN sys.types AS sysType ON ( C.user_type_id = sysType.user_type_id )
WHERE   ( Type = 'U' )
    AND ( C.Name LIKE '%' + @Column_Name + '%' )
    AND ( T.Name LIKE '%' + @Table_Name + '%' )
ORDER BY T.[Name] ,
    C.column_id

这对于使用Sql Server 2008的我来说是有效的:

1
2
3
4
5
6
7
8
9
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

我认为这适用于SQL 2000:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SELECT
    CASE WHEN C.autoval IS NOT NULL THEN
        'Identity'
    ELSE
        'Not Identity'
    AND
FROM
    sysobjects O
INNER JOIN
    syscolumns C
ON
    O.id = C.id
WHERE
    O.NAME = @TableName
AND
    C.NAME = @ColumnName

推荐阅读

    linux控制台编程命令?

    linux控制台编程命令?,系统,工具,环境,命令,名称,标准,不了,工作,发行,基础,s

    linux编程常用命令?

    linux编程常用命令?,系统,工作,信息,命令,地址,管理,工具,网络,基础,目录,lin

    编程解析linux命令?

    编程解析linux命令?,系统,标准,基础,设备,发行,电脑,工具,密码,名字,适当,如

    linux命令行图形编程?

    linux命令行图形编程?,系统,不了,情况,密码,工具,地方,百度,管理,图形界面,

    linux编程执行命令?

    linux编程执行命令?,电脑,系统,环境,命令,基础,发行,工具,代码,地址,名称,lin

    linux磁盘列表命令?

    linux磁盘列表命令?,情况,管理,系统,单位,信息,数据,命令,磁盘,服务,时间,lin

    linux终端命令行编程?

    linux终端命令行编程?,系统,工作,命令,终端,概念,时间,第一,代码,发行,地方,L

    linux编程调用命令?

    linux编程调用命令?,系统,标准,管理,工作,基础知识,情况,环境,设备,基础,首

    linux编程所需的命令?

    linux编程所需的命令?,工作,地址,档案,系统,命令,管理,标准,信息,目录,文件,L

    linux命令筛选列表?

    linux命令筛选列表?,工具,状态,位置,工作,预期,命令,名称,标准,数据,系统,在L

    linux命令行编程乱码?

    linux命令行编程乱码?,环境,统一,乱码,中文,状态,软件,数据,系统,字符集,文

    linux的长列表命令?

    linux的长列表命令?,工作,系统,信息,命令,数据,目录,电脑,软件,时间,设备,Lin

    linux目录列表命令?

    linux目录列表命令?,系统,信息,标准,工作,命令,地址,时间,数据,名称,目录,lin

    linux编程c命令符?

    linux编程c命令符?,工具,代码,系统,保险,环境,文件,程序,命令,终端,编辑,到底

    linux常用编程命令?

    linux常用编程命令?,基础,基础知识,系统,管理,概念,在线,发展,设备,设计,名

    linux命令行界面编程?

    linux命令行界面编程?,系统,环境,代码,密码,命令,终端,首页,软件,工作,电脑,l

    linux命令以服务方式?

    linux命令以服务方式?,服务,系统,标准,设备,工作,命令,网络,操作系统,文件,

    linux命令行编程参数?

    linux命令行编程参数?,网络,信息,系统,实时,状态,情况,工具,服务,环境,分析,L

    linux读取命令方式?

    linux读取命令方式?,位置,信息,工作,管理,命令,软件,图片,名称,发行,环境,lin