Listando índices e restrições


10

Estou procurando em um banco de dados do SQL Server um aplicativo que eu herdei. Não analisei o SQL Server por aproximadamente 10 anos, portanto, tenha paciência comigo.

A tabela de banco de dados que estou vendo possui uma bigint NOT NULLcoluna chamada id, ainda, quando verifico restrições, não vejo nenhuma, e o mesmo vale para todas as tabelas de banco de dados.

Estou certo ao supor que não há chave primária nem indexação (agrupada ou não em cluster) nessas tabelas?

Fiz as seguintes consultas e os resultados parecem confirmar minha suspeita:

//**returns 0**
select count(*) from INFORMATION_SCHEMA.TABLE_CONSTRAINTS;

//**returns no rows**
select * from sys.indexes
where object_id = (select object_id from sys.objects where name = 'NAME-OF-TABLE');

//**returns all tables in database**
SELECT name
FROM sys.tables 
WHERE OBJECTPROPERTY(object_id,'IsIndexed') = 0;

Respostas:


9

Essas duas consultas podem ajudá-lo. O primeiro listará todas as tabelas e índices nessas tabelas no seu banco de dados. Se a tabela não aparecer na lista, não há índices definidos nela. Essas consultas assumem o SQL Server versão 2005 ou mais recente.

SELECT 
    IndexName = QUOTENAME(I.name), 
    TableName =
        QUOTENAME(SCHEMA_NAME(T.[schema_id])) + 
        N'.' + QUOTENAME(T.name), 
    IsPrimaryKey = I.is_primary_key
FROM sys.indexes AS I
INNER JOIN sys.tables AS T
    ON I.[object_id] = T.[object_id]
WHERE
    I.type_desc <> N'HEAP'
ORDER BY 
    TableName ASC, 
    IndexName ASC;

A segunda consulta relatará para cada tabela a coluna de identidade, se houver em cada tabela no seu banco de dados.

SELECT
    TableName =
        QUOTENAME(SCHEMA_NAME(T.[schema_id])) + 
        N'.' + QUOTENAME(T.name), 
    IdentityColumn = COALESCE(QUOTENAME(C.name), N'No identity column')
FROM sys.tables AS T
LEFT OUTER JOIN sys.columns AS C
    ON T.[object_id] = C.[object_id]
    AND C.is_identity = 1
ORDER BY
    TableName ASC;

Para limitar as consultas a uma tabela específica, adicione uma WHEREcláusula semelhante a:

WHERE T.name = N'NAME-OF-TABLE'

2

Não, algo está incorreto.

A verificação sys.indexesdeve retornar uma linha, mesmo que sua tabela não tenha índices. A pilha ainda tem um registro sys.indexescom type_desc'HEAP' e type0.

Eu acho que você provavelmente precisa ter certeza de que está no contexto certo do banco de dados OBJECT_ID()e sys.objectsé específico do banco de dados.

Tente o seguinte:

USE MyDatabase

SELECT *
FROM sys.indexes
WHERE object_id = OBJECT_ID('schema.MyTableName')

1

Não tenho certeza se você está interessado em todas as restrições, mas o INFORMAÇÕES_SCHEMA.TABLE_CONSTRAINTS não parece retornar as restrições DEFAULT - TABLE_CONSTRAINTS (Transact-SQL)

CHEQUE, CHAVE ÚNICA, PRIMÁRIA, CHAVE ESTRANGEIRA

Esta consulta fará uma contagem simples com relação ao sys.objects DMV:

select COUNT(*)
from sys.objects o
where o.type_desc like '%CONSTRAINT%';

Se você estiver interessado em listar as tabelas, poderá executar algo como isto:

select distinct
   o.object_id
 , QUOTENAME(s.name) + '.' + QUOTENAME(o.name) as [object_name]
 , o.type_desc
 , case when dc.parent_object_id is null then 'No' else 'Yes' end as has_default_constraint
 , case when cc.parent_object_id is null then 'No' else 'Yes' end as has_check_constraint
 , case when fk.parent_object_id is null then 'No' else 'Yes' end as has_foreing_key
 , case when kc.parent_object_id is null then 'No' else 'Yes' end as has_primary_key
from sys.objects o
inner join sys.schemas s on s.schema_id = o.schema_id
left outer join sys.default_constraints dc on dc.parent_object_id = o.object_id and dc.schema_id = o.schema_id
left outer join sys.check_constraints cc on cc.parent_object_id = o.object_id and cc.schema_id = o.schema_id
left outer join sys.foreign_keys fk on fk.parent_object_id = o.object_id and fk.schema_id = o.schema_id
left outer join sys.key_constraints kc on kc.parent_object_id = o.object_id and kc.schema_id = o.schema_id
where o.is_ms_shipped = 0
  and o.type = 'U'
order by [object_name];

Este deve fornecer as informações sobre seus índices:

select o.name
 , i.*
from sys.objects o
inner join sys.indexes i on i.object_id = o.object_id
where o.is_ms_shipped = 0
  and i.object_id > 100
  and i.index_id > 0
order by o.name
   , i.index_id;
  • Index_Id = 0 - HEAP (não será exibido)
  • Index_Id = 1 - CLUSTERED
  • Índice_Id> 1 - NÃO EXCLUSIVO

você poderia explicar por que você tem object_id > 100?
Brianc 5/10

@ bluevoodoo1 - não obrigatório, mas <100 são os objetos do sistema, mas como usando o.is_ms_shipped = 0, não deve incluí-los. Apenas jogar pelo seguro, isso é tudo
denist
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.