Как программно определить, какие таблицы SQL имеют столбец идентификаторов

Я хочу создать список столбцов в SQL Server 2005, у которых есть столбцы идентификаторов и соответствующая им таблица в T-SQL.

Результаты будут примерно такими:

TableName, ColumnName

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
104
0
129 485
13
Перейти к ответу Данный вопрос помечен как решенный

Ответы 13

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

Daniel Schaffer 10.09.2010 23:48

Этот ответ также работает с Microsoft SQL Server 2014.

ChrisW 01.07.2016 15:11

В SQL 2005:

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

Я думаю, что это работает для 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 для моей личности.

Kevin Crumley 18.09.2008 01:27

хм ... я использовал status & 128 = 128, чтобы определить свою личность :-P

Brimstedt 17.11.2009 16:17

Этот запрос, кажется, помогает:

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

Другой способ (на 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.

Ответ принят как подходящий

Другой потенциальный способ сделать это для 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 

обратите внимание, что ошибка заключается в том, что вы можете указать [имя базы данных] .information_schema.columns, но запускать из другой базы данных ... и тогда COLUMNPROPERTY работает с неправильной базой данных

Mike M 25.05.2015 17:13

Так лучше, когда у вас есть другие схемы: где COLUMNPROPERTY (object_id (TABLE_SCHEMA + '.' + TABLE_NAME) ...

Hossein Margani 28.06.2015 11:05

Я думаю, что этот ответ не работает с Microsoft SQL Server 2014.

ChrisW 01.07.2016 15:10

Если вы ищете простой подход, который работает начиная с SQL Server 2000, посмотрите этот ответ от @Guillermo.

user692942 29.09.2016 14:09

INFORMATION_SCHEMA.COLUMNS содержит информацию для простых таблиц и взгляды, и я предлагаю добавить TABLE_TYPE (присоединение к INFORMATION_SCHEMA.TABLES) для удобства чтения набора результатов.

Diego Scaravaggi 28.08.2018 10:53

вот рабочая версия для 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;

Это сработало для меня с использованием 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

Использовать это :

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

Список таблиц без столбца 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

Это работало для 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

Для меня работает следующий запрос:

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

По какой-то причине sql-сервер сохраняет некоторые столбцы идентификаторов в разных таблицах, код, который работает для меня, следующий:

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

Другие вопросы по теме