我必须获取所有唯一键约束的列表和特定数据库的索引。我正在做这样的事情:
SELECT * FROM sys.sysobjects WHERE type!='u' AND name LIKE <tablename>
只是想确认这是否是正确的方法,还是有更好的方法做同样的事情?
答案 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]))
这给了我以下结果: