Làm cách nào để bạn xác định Bảng SQL có cột nhận dạng theo lập trình


101

Tôi muốn tạo danh sách các cột trong SQL Server 2005 có các cột nhận dạng và bảng tương ứng của chúng trong T-SQL.

Kết quả sẽ như sau:

TableName, ColumnName

Câu trả lời:


173

Một cách tiềm năng khác để thực hiện việc này cho SQL Server, vốn ít phụ thuộc hơn vào các bảng hệ thống (có thể thay đổi, phiên bản này sang phiên bản khác) là sử dụng dạng xem 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 

lưu ý một điểm cần lưu ý là bạn có thể chỉ định [db name] .information_schema.columns, nhưng chạy từ một db khác ... và sau đó COLUMNPROPERTY đang chạy ngược lại với db sai
Mike M

12
Theo cách này sẽ tốt hơn khi bạn có các lược đồ khác: trong đó COLUMNPROPERTY (object_id (TABLE_SCHEMA + '.' + TABLE_NAME) ...
Hossein Margani

1
Tôi nghĩ rằng câu trả lời này không làm việc với Microsoft SQL Server 2014.
ChrisW

Nếu bạn đang tìm kiếm một cách tiếp cận đơn giản hoạt động từ SQL Server 2000 trở đi, hãy xem câu trả lời này của @Guillermo.
Lankymart

INFORMATION_SCHEMA.COLUMNSchứa thông tin cho các bảng và chế độ xem đơn giản và tôi khuyên bạn nên thêm TABLE_TYPE (tham gia INFORMATION_SCHEMA.TABLES) để có thể đọc được tập kết quả.
Diego Scaravaggi

50

sys.columns.is_identity = 1

ví dụ,

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

2
Lưu ý: điều này hoạt động với tôi trong SQL 2008, trong khi câu trả lời được chấp nhận thì không (câu hỏi yêu cầu cho SQL 2005).
Daniel Schaffer

1
Câu trả lời này cũng làm việc với Microsoft SQL Server 2014.
ChrisW

27

Một cách khác (cho 2000/2005/2012/2014):

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

LƯU Ý: table_name_herenên như vậy schema.table, trừ khi có lược đồ dbo.


6

Trong SQL 2005:

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

3

Truy vấn này dường như thực hiện thủ thuật:

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

2

đây là phiên bản làm việc cho MSSQL 2000. Tôi đã sửa đổi mã 2005 được tìm thấy ở đây: 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;

2

Danh sách các bảng không có cột Identity dựa trên câu trả lời 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

2

Truy vấn sau phù hợp với tôi:

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

Tôi nghĩ rằng điều này hoạt động cho 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

Tôi không biết tự động xác thực làm gì, nhưng nó NULL cho tất cả các trường danh tính của tôi. Mã SQL 2000 mà tôi có hoạt động là ở đâu colstat & 1 = 1 Tôi không chắc mã đó đến từ đâu (nó khoảng 5 năm tuổi), nhưng nhận xét của tôi nói rằng một mặt nạ bit là cần thiết. Nhưng colstat = 1 cho danh tính của tôi.
Kevin Crumley 17/09/08

hmm ... tôi sử dụng trạng thái & 128 = 128 để xác định bản sắc của tôi :-P
Brimstedt

1

Điều này làm việc cho tôi khi sử dụng 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

1

Dùng cái này :

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

1

Điều này hoạt động cho SQL Server 2005, 2008 và 2012. Tôi nhận thấy rằng sys.identity_columns không chứa tất cả các bảng có cột nhận dạng của tôi.

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;

Nhìn vào trang tài liệu, cột trạng thái cũng có thể được sử dụng. Ngoài ra, bạn có thể thêm số nhận dạng bốn phần và nó sẽ hoạt động trên các máy chủ khác nhau.

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;

Nguồn: https://msdn.microsoft.com/en-us/library/ms186816.aspx


1

Bởi một số lý do máy chủ sql lưu một số cột nhận dạng trong các bảng khác nhau, mã phù hợp với tôi, như sau:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.