Как определить, какие таблицы SQL имеют столбец идентификаторов программно - PullRequest
91 голосов
/ 18 сентября 2008

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

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

TableName, ColumnName

Ответы [ 13 ]

161 голосов
/ 18 сентября 2008

Еще один потенциальный способ сделать это для 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 
46 голосов
/ 18 сентября 2008

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
26 голосов
/ 18 сентября 2008

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

5 голосов
/ 18 сентября 2008

В SQL 2005:

select object_name(object_id), name
from sys.columns
where is_identity = 1
2 голосов
/ 18 сентября 2008

Этот запрос, кажется, делает свое дело:

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 голос
/ 08 января 2015

Список таблиц без столбца Identity на основе Guillermo ответ:

SELECT DISTINCT TABLE_NAME
FROM            INFORMATION_SCHEMA.COLUMNS
WHERE        (TABLE_SCHEMA = 'dbo') AND (OBJECTPROPERTY(OBJECT_ID(TABLE_NAME), 'TableHasIdentity') = 0)
ORDER BY TABLE_NAME
1 голос
/ 17 февраля 2011

вот рабочая версия для 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;
0 голосов
/ 12 июля 2018

По какой-то причине 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
0 голосов
/ 12 июля 2018

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

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
0 голосов
/ 18 октября 2016

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

...