2017-12-24 18 views
2

Basierend auf SQL Server Schema Collections möchte ich sqlConnection.GetSchema("IndexColumns"); verwenden, um zu bestimmen, welche Spalten primäre Schlüssel sind.Wo kann ich SQL-Schlüsseltypcodes überprüfen?

habe ich einige Experimente und festgestellt, dass mit der obigen Anfrage ich eine Datentabelle mit den folgenden Informationen erhalten:

table_catalog table_schema table_name    column_name ordinal_position KeyType index_name 
--------------------------------------------------------------------------------------------------------------------------- 
TestDb   dbo   TestTableWithPrimaryKey  Id    1    56  PK_TestTableWithPrimaryKey 

I KeyType = 56 steht für Primärschlüssel erraten, aber dies nur aus dieser Tabelle abgeleitet wird definition:

Ich möchte überprüfen, ob mein Ergebnis korrekt ist, bevor ich es tatsächlich in einem Projekt verwende. Gibt es einen Ort, wo ich alle Schlüsseltypen bekommen kann?

Antwort

1

Durch am internen SqlMetaDataFactory sucht der Aufruf an sqlConnection.GetSchema("IndexColumns"); nicht Lookup, die wie in der Ressourcendatei System.Data.SqlClient.SqlMetaData.xml gefunden ausführen Befehl und das wird uns zeigen Indexcolumns

<MetaDataCollections> 
    <CollectionName>IndexColumns</CollectionName> 
    <NumberOfRestrictions>5</NumberOfRestrictions> 
    <NumberOfIdentifierParts>4</NumberOfIdentifierParts> 
    <PopulationMechanism>SQLCommand</PopulationMechanism> 
    <PopulationString>EXEC sys.sp_indexcolumns_managed @Catalog, @Owner, @Table, @ConstraintName, @Column</PopulationString> 
    <MinimumVersion>10.00.0000</MinimumVersion> 
    </MetaDataCollections> 

Das bedeutet, dass Es wird ausgeführt . Die gespeicherte Prozedur wird mit EXEC sp_helptext 'sys.sp_indexcolumns_managed' zeigen, dass es aus sys.spt_indexcolumns_view_managed und diese Ansicht wählt ist definiert als:

select distinct 
    db_Name() as constraint_catalog, 
    constraint_schema = SCHEMA_NAME(o.schema_id), 
    constraint_name = x.name, 
    table_catalog = db_name(), 
    table_schema = SCHEMA_NAME(o.schema_id), 
    table_name = o.name, 
    column_name = c.name, 
    ordinal_position = xc.key_ordinal, 
    KeyType = c.system_type_id, 
    index_name = x.name 
from 
    sys.objects o INNER JOIN sys.indexes x ON 
     (
      o.object_id = x.object_id AND 
      o.type in ('U') 
     ) INNER JOIN 
    sys.index_columns xc ON 
     (
      xc.object_id = x.object_id AND 
      xc.index_id = x.index_id 
     ) INNER JOIN 
    sys.columns c ON 
     (
      o.object_id = c.object_id AND 
      xc.column_id = c.column_id 
     ) 

(Sie können ihre Definition mit SELECT OBJECT_DEFINITION(OBJECT_ID('sys.sp_indexcolumns_managed')); finden, weil es Teil der Resource Database ist)

Jetzt können wir sehen, dass die Säule KeyType über sys.columns.system_type_id projiziert, die in sys.columns als

ID des Systemtyp der Spalte dokumentiert ist.

und Where do I find Sql Server metadata for column datatypes? Details, die mit sys.types Beitritt geben Ihnen die Informationen von der Art der Spalte.

Bewaffnet mit dieser Information können wir bereits feststellen, dass ich KeyType = erraten 56 steht für Primärschlüssel ist nicht wahr, und

select name, system_type_id, user_type_id, schema_id, max_length, precision scale 
from sys.types 
where system_type_id = 56 

laufen

name system_type_id user_type_id schema_id max_length scale 
---- -------------- ------------ --------- ---------- ----- 
int 56    56   4   4   10  

zurück und das ist die columntype, nicht wenn es der Primärschlüssel ist.

Es scheint keinen zuverlässigen Weg zu geben, den Primärschlüssel mit dem GetSchema-Aufruf AFAICT zu finden. Verwenden Sie die Abfrage, die von Dan Guzman bereitgestellt wird.

+0

Das ist wirklich eine erstaunliche Detektivarbeit. Ich kenne SQL nicht so gut, also wäre ich nicht einmal halb so weit gekommen - und ich habe viel von deiner Antwort gelernt. Es ist schade, dass sie einen so verwirrenden Namen _KeyType_ gewählt haben, der an anderen Stellen korrekt _DataType_ heißt. Ich werde diese Antwort akzeptieren, weil sie bis zum Ende der magischen Zahl 56 geht, die ich verifizieren wollte, und sie zeigt auch ein paar neue Werkzeuge, wie ich das in Zukunft selbst machen könnte - obwohl ich als eine Plan B Lösung habe um zu dem zu wechseln, was @DanGuzman vorgeschlagen hat, als sich meine Theorie als falsch herausstellte. – t3chb0t

3

KeyType Die Spalte wird an die Spaltendatentyp abzubilden, wie durch den SQL Server sys.types Katalogansicht system_type Spalte aufgezählt (Wert 56 ist int). Folglich wird dies nicht helfen, die Spalte als Mitglied des Primärschlüssels zu identifizieren.

Es gibt mehrere Methoden zum Abrufen von SQL Server-Primärschlüsselspalten, einschließlich SMO- und Katalogansichtsabfragen. Im Folgenden finden Sie ein Beispiel zum Abrufen aller Primärschlüsselspalten in der Datenbank für SQL Server. Wenn Sie mehrere DBMS-Produkte unterstützen müssen, können Sie stattdessen die Katalogsichten INFORMATION_SCHEMA für DBMS-Produkte verwenden, die diese ANSI-Standardansichten implementieren.

SELECT 
     OBJECT_SCHEMA_NAME(i.object_id) AS SchemaName 
    , OBJECT_NAME(i.object_id) AS TableName 
    , c.name AS ColumnName 
    , ic.key_ordinal AS KeyOrdinal 
FROM sys.key_constraints AS kc 
JOIN sys.indexes AS i ON i.object_id = kc.parent_object_id AND kc.name = i.name 
JOIN sys.index_columns AS ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id 
JOIN sys.columns AS c ON c.object_id = ic.object_id AND c.column_id = ic.column_id 
WHERE kc.type_desc = N'PRIMARY_KEY_CONSTRAINT' 
ORDER BY 
     SchemaName 
    , TableName 
    , KeyOrdinal;