获取数据库中唯一约束和索引的列表

时间:2012-08-13 19:39:23

标签: sql sql-server sql-server-2008

我必须获取所有唯一键约束的列表和特定数据库的索引。我正在做这样的事情:

SELECT * FROM sys.sysobjects WHERE type!='u' AND name LIKE <tablename> 

只是想确认这是否是正确的方法,还是有更好的方法做同样的事情?

5 个答案:

答案 0 :(得分:7)

由于唯一约束作为索引在封面下实现,因此您可以直接从sys.indexes获取所有这些信息:

SELECT
  [schema] = OBJECT_SCHEMA_NAME([object_id]),
  [table]  = OBJECT_NAME([object_id]),
  [index]  = name, 
  is_unique_constraint,
  is_unique,
  is_primary_key
FROM sys.indexes
-- WHERE [object_id] = OBJECT_ID('dbo.tablename');

重复所有数据库(可能没有特定表格的过滤器):

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += 'SELECT db = ' + name + ',
    [schema] = OBJECT_SCHEMA_NAME([object_id]),
    [table]  = OBJECT_NAME([object_id]),
    [index]  = name, 
    is_unique_constraint,
    is_unique,
    is_primary_key
  FROM ' + QUOTENAME(name) + '.sys.indexes;'
FROM sys.databases
WHERE database_id BETWEEN 4 AND 32766;

EXEC sp_executesql @sql;

答案 1 :(得分:1)

一个唯一约束在sys.objects中由类型'UQ'

表示
 select name from sys.objects where type='UQ'

获取索引

 select i.name, o.name from sys.indexes i
inner join sys.objects o on i.object_id= o.object_id

答案 2 :(得分:1)

您可以从sys.indexes获取唯一键约束和索引。 具体而言,唯一约束:

select * from sys.indexes where is_unique_constraint = 1

答案 3 :(得分:0)

其他答案没有为我返回完整列表。此查询对我有用,可返回不是主键或系统表的所有唯一索引:

select i.name as index_name, o.name as object_name
from sys.indexes i
    join sys.objects o on i.object_id= o.object_id
where (i.is_unique_constraint = 1 OR i.is_unique = 1) 
    and i.is_primary_key = 0 and o.type_desc <> 'SYSTEM_TABLE'

答案 4 :(得分:0)

我正在寻找解决方案 - 查找特定表上的所有唯一索引。 我以这个问题为出发点。

最后我整理了自己的脚本,在这里分享。

这个脚本的好处是它给出了索引的列。

所有荣耀归原脚本作者所有,链接已包含在代码中。

--====================================================================================
-- Display SQL Server Index Details – Type, Key Columns, Included Columns
-- https://www.ptr.co.uk/blog/sql-server-display-indexes-their-columns-included-columns
--====================================================================================


--Display all indexes along with key columns, included columns and index type

DECLARE @TempTable AS TABLE (SchemaName VARCHAR(100), 
                             ObjectID INT, 
                             TableName VARCHAR(100), 
                             IndexID INT, 
                             IndexName VARCHAR(100), 
                             ColumnID INT, 
                             column_index_id INT, 
                             ColumnNames  VARCHAR(500), 
                             IncludeColumns  VARCHAR(500), 
                             NumberOfColumns INT, 
                             IndexType  VARCHAR(20),
                             IS_UNIQUE BIT,
                             Is_Primary_Key BIT,
                             Is_Unique_Constraint BIT,
                             LastColRecord INT);

WITH CTE_Indexes (SchemaName, ObjectID, TableName, IndexID, IndexName, 
                  ColumnID, column_index_id, ColumnNames, IncludeColumns, 
                  NumberOfColumns, IndexType, Is_Unique,Is_Primary_Key,Is_Unique_Constraint)
AS
(
SELECT s.name, t.object_id, t.name, i.index_id, i.name, c.column_id, ic.index_column_id,
        CASE ic.is_included_column WHEN 0 THEN CAST(c.name AS VARCHAR(5000)) ELSE '' END, 
        CASE ic.is_included_column WHEN 1 THEN CAST(c.name AS VARCHAR(5000)) ELSE '' END, 
        1, i.type_desc,I.is_unique,i.Is_Primary_Key,i.Is_Unique_Constraint 
    FROM  sys.schemas AS s
        JOIN sys.tables AS t ON s.schema_id = t.schema_id
            JOIN sys.indexes AS i ON i.object_id = t.object_id
                JOIN sys.index_columns AS ic 
                  ON ic.index_id = i.index_id 
                 AND ic.object_id = i.object_id
                    JOIN sys.columns AS c 
                      ON c.column_id = ic.column_id 
                     AND c.object_id = ic.object_id
                     AND ic.index_column_id = 1
UNION ALL
SELECT s.name, t.object_id, t.name, i.index_id, i.name, c.column_id, ic.index_column_id,
        CASE ic.is_included_column WHEN 0 THEN CAST(cte.ColumnNames + ', ' + c.name AS VARCHAR(5000))  
                                          ELSE cte.ColumnNames END, 
        CASE  
            WHEN ic.is_included_column = 1 AND cte.IncludeColumns != '' 
                THEN CAST(cte.IncludeColumns + ', ' + c.name AS VARCHAR(5000))
            WHEN ic.is_included_column =1 AND cte.IncludeColumns = '' 
                THEN CAST(c.name AS VARCHAR(5000)) 
            ELSE '' 
        END,
        cte.NumberOfColumns + 1, i.type_desc,I.is_unique,I.Is_Primary_Key,i.Is_Unique_Constraint 
    FROM  sys.schemas AS s
        JOIN sys.tables AS t ON s.schema_id = t.schema_id
            JOIN sys.indexes AS i ON i.object_id = t.object_id
                JOIN sys.index_columns AS ic 
                  ON ic.index_id = i.index_id 
                 AND ic.object_id = i.object_id
                    JOIN sys.columns AS c 
                      ON c.column_id = ic.column_id 
                     AND c.object_id = ic.object_id 
                    JOIN CTE_Indexes cte 
                      ON cte.Column_index_ID + 1 = ic.index_column_id  
                    --JOIN CTE_Indexes cte ON cte.ColumnID + 1 = ic.index_column_id  
                     AND cte.IndexID = i.index_id AND cte.ObjectID = ic.object_id

)
INSERT INTO  @TempTable 
SELECT *, 
  RANK() OVER (PARTITION BY ObjectID, IndexID ORDER BY NumberOfColumns DESC) AS LastRecord 
  FROM CTE_Indexes AS cte;

SELECT SchemaName, TableName, IndexName, ColumnNames, IncludeColumns, IndexType, Is_Unique,Is_Primary_Key,Is_Unique_Constraint   
  FROM @TempTable
 WHERE LastColRecord = 1
 --WHERE T.object_id=OBJECT_ID('dbo.invoiceSelectedOptionalFees')
 --AND objectid=OBJECT_ID('dbo.accountTransaction')
 AND objectid=OBJECT_ID('dbo.invoiceSelectedOptionalFees')
ORDER BY objectid, TableName, indexid, IndexName

在上面的例子中,我使用了下表:

IF OBJECT_ID('[dbo].[invoiceSelectedOptionalFees]') IS NOT NULL 
DROP TABLE [dbo].[invoiceSelectedOptionalFees] 
GO
CREATE TABLE [dbo].[invoiceSelectedOptionalFees] ( 
[Id]         INT              IDENTITY(1,1)                 NOT NULL,
[invoiceId]  INT                              NOT NULL,
[feeTypeId]  INT                              NOT NULL,
CONSTRAINT   [PK__invoiceS__3214EC0703C8693D]  PRIMARY KEY CLUSTERED    ([Id] asc),
CONSTRAINT   [CK_invoiceSelectedOptionalFees_invoice_feeType]  UNIQUE      NONCLUSTERED ([invoiceId] asc, [feeTypeId] asc),
CONSTRAINT   [FK_invoiceSelectedOptionalFees_invoice]                      FOREIGN KEY ([invoiceId]) REFERENCES [invoice]([invoiceID]),
CONSTRAINT   [FK_invoiceSelectedOptionalFees_feeTypes]                     FOREIGN KEY ([feeTypeId]) REFERENCES [feeTypes]([feeTypeID]))

这给了我以下结果:

enter image description here