2011-11-01 6 views
0

J'ai réussi à concocter cette requête à partir de divers exemples pour obtenir toutes les clés de la table:Obtenir toutes les clés de la table avec des types

select tbl.name,idx.name as indexname,t1.*,col.name as colname 
from dbo.sysindexkeys as t1 
LEFT JOIN dbo.sysindexes as idx on (t1.id=idx.id and t1.indid=idx.indid) 
LEFT JOIN dbo.syscolumns as col on (col.id=t1.id and col.colid=t1.colid) 
LEFT JOIN dbo.sysobjects as tbl on (idx.id=tbl.id) 
ORDER BY tbl.name,idx.name,t1.keyno 

La seule autre chose que je dois est le type des clés, qui, comme je comprendre devrait être PK, UQ, ou D (pas concerné par les clés étrangères pour le moment). Il semble que je dois rejoindre sysobjects à nouveau pour obtenir la colonne xtype, mais je ne peux pas comprendre la bonne façon de faire la jointure.

Basé sur this answer J'ai essayé

select tbl.name,idx.name as indexname,s2.xtype,t1.*,col.name as colname 
from dbo.sysindexkeys as t1 
LEFT JOIN dbo.sysindexes as idx on (t1.id=idx.id and t1.indid=idx.indid) 
JOIN sysobjects s2 on s2.parent_obj = t1.id 
LEFT JOIN dbo.syscolumns as col on (col.id=t1.id and col.colid=t1.colid) 
LEFT JOIN dbo.sysobjects as tbl on (idx.id=tbl.id) 
ORDER BY tbl.name,idx.name,t1.keyno 

mais cela se traduit dans plusieurs enregistrements par colonne d'index et avec différents xtypes. Je veux une ligne par colonne d'index (si l'index est sur trois colonnes, alors il devrait y avoir trois rangées) toutes avec le bon xtype. De quoi ai-je besoin pour changer?

+1

Quelle version de SQL Server êtes-vous? Toutes ces vues sont obsolètes. –

+0

'select @@ Version': Microsoft SQL Server 2000 - 8.00.760 (Intel X86) 17 décembre 2002 14:22:05 Copyright (c) 1988-2003 Microsoft Office Desktop Engine sur Windows NT 5.1 (Build 2600: Service Pack 2 –

Répondre

1

Vous pouvez essayer d'utiliser status de sysindexes pour déterminer le type de clé. La requête pourrait être sur les points suivants

SELECT c.name AS [schema], a.name AS table_name, b.name AS key_name, 
    CAST(CASE WHEN b.status&2048<>0 THEN 1 ELSE 0 END AS bit) AS is_PK_constraint, 
    CAST(CASE WHEN b.status&4096<>0 THEN 1 ELSE 0 END AS bit) AS is_UNIQUE_constraint, 
    CAST(CASE WHEN b.status&16<>0 THEN 1 ELSE 0 END AS bit) AS is_clustered, 
    CAST(CASE WHEN b.status&2<>0 THEN 1 ELSE 0 END AS bit) AS is_unique_index, 
    CAST(CASE WHEN b.status&64<>0 THEN 1 ELSE 0 END AS bit) AS is_allows_duplicate 
FROM sysobjects a 
    INNER JOIN sysindexes b ON a.id = b.id 
    INNER JOIN sysusers c ON a.uid = c.uid 
WHERE b.status&0x800000=0 AND c.name<>'sys' 
ORDER BY c.name, a.name, b.name 

J'espère que cela fonctionnera dans la version rétro de SQL Server (SQL Server 2000) que vous utilisez actuellement.

1

Je suis allé dans votre déclaration sql original et a obtenu pour retourner le xtype pour l'indice de la table sysobjects:

select tbl.name,idx.name as indexname,t1.*,col.name as colname, tbl2.xtype 
from dbo.sysindexkeys as t1 
LEFT JOIN dbo.sysindexes as idx on (t1.id=idx.id and t1.indid=idx.indid) 
LEFT JOIN dbo.syscolumns as col on (col.id=t1.id and col.colid=t1.colid) 
LEFT JOIN dbo.sysobjects as tbl on (idx.id=tbl.id) 
JOIN dbo.sysobjects AS tbl2 ON (idx.id = tbl2.parent_obj) AND (idx.name = tbl2.name) 
ORDER BY tbl.name,idx.name,t1.keyno 

Le idx.id est l'id de la table l'index est lié à. Il n'y a rien dans la table sysobjects à l'exception du champ de nom qui correspond à ce qui est dans la table sysindexes, donc nous avons dû nous joindre à cela aussi. Presque un autre a quitté la jointure, mais quand je l'ai fait, j'ai obtenu des lignes de la table d'index pour les objets statistiques qui ne sont pas répertoriés dans la table sysobjects.

EDIT: Je suis retourné et regardé ce qu'il faudrait pour obtenir l'information que vous recherchez et est venu avec l'instruction SQL suivante:

SELECT name, indexname, id, indid, colid, keyno, colname, 
    ISNULL(xtype, CASE WHEN is_index = 1 THEN 'IX' WHEN status&2 <> 0 THEN 'UQ' ELSE xtype END) as xtype 
FROM 
(select TOP 100 PERCENT 
    tbl.name, 
    idx.name as indexname, 
    t1.*, 
    col.name as colname, 
    idx.status, 
    CAST(CASE WHEN (idx.status=0 OR idx.status&5<>0) THEN 1 ELSE 0 END AS bit) AS is_index, 
    CAST(CASE WHEN idx.status&64<>0 THEN 1 ELSE 0 END AS bit) AS is_statistic, 
    tbl2.xtype 
from dbo.sysindexkeys as t1 
LEFT JOIN dbo.sysindexes as idx on (t1.id=idx.id and t1.indid=idx.indid) 
LEFT JOIN dbo.syscolumns as col on (col.id=t1.id and col.colid=t1.colid) 
LEFT JOIN dbo.sysobjects as tbl on (idx.id=tbl.id) 
LEFT JOIN dbo.sysobjects AS tbl2 ON (idx.id = tbl2.parent_obj) AND (idx.name = tbl2.name) 
ORDER BY tbl.name,idx.name,t1.keyno) AS dts 
WHERE is_statistic = 0 

Je ne sais pas comment obtenir le 'D' Les types à afficher car ils ne sont pas dans la table sysindexkeys non plus.

+0

Cela semble retourner uniquement les clés primaires lorsque je l'exécute. Je n'ai pas assez d'expérience avec MS SQL pour deviner pourquoi. –

+0

Après avoir regardé un peu plus. Il semble que les index normaux ne se trouvent pas dans la table sysobjects de Sql Server 2000. À cause de cela, la jointure les exclut. Vous ne savez pas comment le modifier pour afficher les index sans afficher de statistiques. Si vous modifiez le dernier JOIN à un LEFT JOIN alors vous obtiendrez les éléments qui sont dans la table sysindexes même s'ils ne sont pas dans la table sysobjects. –

Questions connexes