Auflisten von Indizes und Einschränkungen


10

Ich suche in einer SQL Server-Datenbank nach einer Anwendung, die ich geerbt habe. Ich habe mich seit ungefähr 10 Jahren nicht mehr mit SQL Server befasst. Bitte nehmen Sie Kontakt mit mir auf.

Die Datenbanktabelle, die ich betrachte, hat eine bigint NOT NULLSpalte mit dem Namen id. Wenn ich jedoch nach Einschränkungen suche , werden keine angezeigt. Dies gilt auch für alle Datenbanktabellen.

Habe ich Recht, wenn ich davon ausgehe, dass für diese Tabellen kein Primärschlüssel und keine Indizierung (gruppiert oder nicht gruppiert) vorhanden ist?

Ich habe die folgenden Abfragen durchgeführt und die Ergebnisse scheinen meinen Verdacht zu bestätigen:

//**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;

Antworten:


9

Diese beiden Abfragen können Ihnen helfen. Der erste listet alle Tabellen und Indizes für diese Tabellen in Ihrer Datenbank auf. Wenn die Tabelle nicht in der Liste angezeigt wird, sind keine Indizes definiert. Diese Abfragen setzen SQL Server Version 2005 oder neuer voraus.

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;

Die zweite Abfrage meldet für jede Tabelle die Identitätsspalte, falls vorhanden, für jede Tabelle in Ihrer Datenbank.

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;

Um die Abfragen auf eine bestimmte Tabelle zu beschränken, fügen Sie eine WHEREKlausel hinzu, die der folgenden ähnelt:

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

2

Nein, etwas stimmt nicht.

Das Einchecken sys.indexessollte eine Zeile zurückgeben, auch wenn Ihre Tabelle keine Indizes enthält. Der Heap hat noch einen Datensatz sys.indexesmit einem type_descvon 'HEAP' und typevon 0.

Ich denke, Sie müssen wahrscheinlich sicherstellen, dass Sie sich seitdem im richtigen Datenbankkontext befinden OBJECT_ID()und sys.objectsdatenbankspezifisch sind.

Versuche dies:

USE MyDatabase

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

1

Ich bin nicht sicher, ob Sie an allen Einschränkungen interessiert sind, aber INFORMATION_SCHEMA.TABLE_CONSTRAINTS scheint die DEFAULT-Einschränkungen nicht zurückzugeben - TABLE_CONSTRAINTS (Transact-SQL)

PRÜFEN, EINZIGARTIG, PRIMÄRER SCHLÜSSEL, AUSLÄNDISCHER SCHLÜSSEL

Diese Abfrage führt eine einfache Zählung für die DMV sys.objects durch:

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

Wenn Sie daran interessiert sind, die Tabellen aufzulisten, können Sie Folgendes ausführen:

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

Dieser sollte Ihnen die Informationen zu Ihren Indizes geben:

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 (wird nicht angezeigt)
  • Index_Id = 1 - CLUSTERED
  • Index_Id> 1 - NICHT CLUSTERED

Können Sie erklären, warum Sie haben object_id > 100?
Brianc

@ bluevoodoo1 - nicht obligatorisch, aber <100 sind die Systemobjekte, aber da o.is_ms_shipped = 0 verwendet wird, sollten sie sowieso nicht enthalten sein. Nur auf
Nummer
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.