【问题标题】:How do you determine what SQL Tables have an identity column programmatically如何以编程方式确定哪些 SQL 表具有标识列
【发布时间】:2010-09-10 09:45:18
【问题描述】:

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

结果会是这样的:

表名、列名

【问题讨论】:

    标签: sql-server tsql metadata identity-column


    【解决方案1】:

    对 SQL Server 执行此操作的另一种可能方法是使用 INFORMATION_SCHEMA 浏览量:

    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 
    

    【讨论】:

    • 注意一个问题是您可以指定 [db name].information_schema.columns ,但从不同的数据库运行...然后 COLUMNPROPERTY 针对错误的数据库运行
    • 当你有其他模式时,这种方式会更好: where COLUMNPROPERTY(object_id(TABLE_SCHEMA+'.'+TABLE_NAME)...
    • 我认为这个答案不适用于 Microsoft SQL Server 2014。
    • 如果您正在寻找一种从 SQL Server 2000 开始工作的简单方法,请查看 @Guillermo 的 this answer
    • INFORMATION_SCHEMA.COLUMNS 包含普通表和 视图 的信息,我建议添加 TABLE_TYPE(加入 INFORMATION_SCHEMA.TABLES)以提高结果集的可读性。
    【解决方案2】:

    sys.columns.is_identity = 1

    例如,

    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
    

    【讨论】:

    • 注意:这适用于我在 SQL 2008 中,而接受的答案不适用(问题要求 SQL 2005)。
    • 此答案也适用于 Microsoft SQL Server 2014。
    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

      在 SQL 2005 中:

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

      【讨论】:

        【解决方案5】:

        这个查询似乎可以解决问题:

        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')
        

        【讨论】:

          【解决方案6】:

          基于Guillermo答案的没有Identity列的表列表:

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

          【讨论】:

            【解决方案7】:

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

            /* 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;
            

            【讨论】:

              【解决方案8】:

              以下查询对我有用:

              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
              

              【讨论】:

                【解决方案9】:

                我认为这适用于 SQL 2000:

                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
                

                【讨论】:

                • 我不知道 autoval 是做什么的,但我的所有身份字段都是 NULL。我拥有的 SQL 2000 代码是 colstat & 1 = 1 我不确定该代码来自哪里(大约有 5 年的历史),但我的评论说位掩码是必要的。但是 colstat = 1 代表我的身份。
                • hmm... 我使用 status & 128 = 128 来确定我的身份:-P
                【解决方案10】:

                这对我使用 Sql Server 2008 有效:

                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
                

                【讨论】:

                  【解决方案11】:

                  使用这个:

                  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
                  

                  【讨论】:

                    【解决方案12】:

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

                    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;
                    

                    查看文档页面,也可以使用状态列。您还可以添加四部分标识符,它将在不同的服务器上工作。

                    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/en-us/library/ms186816.aspx

                    【讨论】:

                      【解决方案13】:

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

                      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
                      

                      【讨论】:

                        猜你喜欢
                        • 2017-03-24
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2010-09-08
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多