Liste des index et des contraintes

10

Je recherche une base de données SQL Server pour une application dont j'ai hérité. Je n'ai pas examiné SQL Server depuis environ 10 ans, alors soyez indulgent avec moi.

La table de base de données que je regarde a une bigint NOT NULLcolonne appelée id, pourtant, quand je vérifie les contraintes, je n'en vois pas, et il en va de même pour toutes les tables de base de données.

Ai-je raison de supposer qu'il n'y a pas de clé primaire et pas d'indexation (en cluster ou non-cluster) sur ces tables?

J'ai exécuté les requêtes suivantes et les résultats semblent confirmer mes soupçons:

//**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;
Ali Haider
la source

Réponses:

9

Ces deux requêtes peuvent vous aider. Le premier répertorie toutes les tables et index de ces tables dans votre base de données. Si la table n'apparaît pas dans la liste, aucun index n'y est défini. Ces requêtes supposent SQL Server version 2005 ou plus récente.

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;

La deuxième requête signale pour chaque table la colonne d'identité, le cas échéant sur chaque table de votre base de données.

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;

Pour limiter les requêtes à une table spécifique, ajoutez une WHEREclause similaire à:

WHERE T.name = N'NAME-OF-TABLE'
Jeremy
la source
2

Non, quelque chose est incorrect.

La vérification sys.indexesdoit renvoyer une ligne même si votre table n'a pas d'index. Le tas a toujours un record sys.indexesavec un type_descde 'HEAP' et typede 0.

Je pense que vous devez probablement vous assurer que vous êtes dans le bon contexte de base de données depuis OBJECT_ID()et que vous sys.objectsêtes spécifique à la base de données.

Essaye ça:

USE MyDatabase

SELECT *
FROM sys.indexes
WHERE object_id = OBJECT_ID('schema.MyTableName')
JNK
la source
1

Je ne sais pas si vous êtes intéressé par toutes les contraintes mais INFORMATION_SCHEMA.TABLE_CONSTRAINTS ne semble pas renvoyer les contraintes DEFAULT - TABLE_CONSTRAINTS (Transact-SQL)

CHECK, UNIQUE, PRIMARY KEY, FOREIGN KEY

Cette requête fera un simple décompte par rapport au DMV sys.objects:

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

Si vous souhaitez répertorier les tableaux, vous pouvez exécuter quelque chose comme ceci:

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];

Celui-ci devrait vous donner les informations sur vos index:

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'apparaîtra pas)
  • Index_Id = 1 - CLUSTERED
  • Index_Id> 1 - NON CLUSTERED
DenisT
la source
pourriez-vous expliquer pourquoi vous en avez object_id > 100?
brianc
@ bluevoodoo1 - pas obligatoire mais <100 sont les objets système mais depuis que vous utilisez o.is_ms_shipped = 0, vous ne devez pas les inclure de toute façon. Jouer en toute sécurité, c'est tout
DenisT