2008-09-18 7 views

Répondre

113
SELECT Col.Column_Name from 
    INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab, 
    INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col 
WHERE 
    Col.Constraint_Name = Tab.Constraint_Name 
    AND Col.Table_Name = Tab.Table_Name 
    AND Constraint_Type = 'PRIMARY KEY' 
    AND Col.Table_Name = '<your table name>' 
+0

FYI cela ne liste pas nécessairement les colonnes *en ordre*. Voir cette réponse à une question similaire si vous avez besoin des colonnes dans leur ordre particulier: http://stackoverflow.com/a/3942921/18511 – Kip

+6

En fait, je crois que vous devez également contraindre par Schema, non? Donc, vous devez ajouter "Et COL.TABLE_SCHEMA = ''". – DavidStein

+0

Si la requête ci-dessus renvoie 3 lignes, 'a',' b' et 'c', (dans cet ordre) alors ma table a une clé composite primaire de' abc'? –

0

La procédure stockée système sp_help vous donnera les informations. Exécutez l'instruction suivante:

execute sp_help table_name 
5

utilise-t-MS SQL Server, vous pouvez effectuer les opérations suivantes:

--List all tables primary keys 
select * from information_schema.table_constraints 
where constraint_type = 'Primary Key' 

Vous pouvez également filtrer sur la colonne nom_table si vous voulez une table spécifique.

+3

ceci ne liste que la clé, il ne liste pas les colonnes dans la clé – Kip

+0

Ceci est bien parti, mais doit être joint à INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE comme dans la réponse de Guy Starbuck. – bstrong

0

pour cette solution:

SELECT 
    CONSTRAINT_CATALOG AS DataBaseName, 
    CONSTRAINT_SCHEMA AS SchemaName, 
    TABLE_NAME AS TableName, 
    CONSTRAINT_Name AS PrimaryKey 
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
WHERE CONSTRAINT_TYPE = 'Primary Key' and Table_Name = 'YourTable' 
0
SELECT t.name AS 'table', i.name AS 'index', it.xtype, 

(SELECT c.name FROM syscolumns c INNER JOIN sysindexkeys k 
    ON k.indid = i.indid 
     AND c.colid = k.colid 
     AND c.id = t.id 
     AND k.keyno = 1 
     AND k.id = t.id) 
    AS 'column1', 

(SELECT c.name FROM syscolumns c INNER JOIN sysindexkeys k 
    ON k.indid = i.indid 
     AND c.colid = k.colid 
     AND c.id = t.id 
     AND k.keyno = 2 
     AND k.id = t.id) 
    AS 'column2', 

(SELECT c.name FROM syscolumns c INNER JOIN sysindexkeys k 
    ON k.indid = i.indid 
     AND c.colid = k.colid 
     AND c.id = t.id 
     AND k.keyno = 3 
     AND k.id = t.id) 
    AS 'column3', 

(SELECT c.name FROM syscolumns c INNER JOIN sysindexkeys k 
    ON k.indid = i.indid 
     AND c.colid = k.colid 
     AND c.id = t.id 
     AND k.keyno = 4 
     AND k.id = t.id) 
    AS 'column4', 

(SELECT c.name FROM syscolumns c INNER JOIN sysindexkeys k 
    ON k.indid = i.indid 
     AND c.colid = k.colid 
     AND c.id = t.id 
     AND k.keyno = 5 
     AND k.id = t.id) 
    AS 'column5', 

(SELECT c.name FROM syscolumns c INNER JOIN sysindexkeys k 
    ON k.indid = i.indid 
     AND c.colid = k.colid 
     AND c.id = t.id 
     AND k.keyno = 6 
     AND k.id = t.id) 
    AS 'column6', 

(SELECT c.name FROM syscolumns c INNER JOIN sysindexkeys k 
    ON k.indid = i.indid 
     AND c.colid = k.colid 
     AND c.id = t.id 
     AND k.keyno = 7 
     AND k.id = t.id) 
    AS 'column7', 

(SELECT c.name FROM syscolumns c INNER JOIN sysindexkeys k 
    ON k.indid = i.indid 
     AND c.colid = k.colid 
     AND c.id = t.id 
     AND k.keyno = 8 
     AND k.id = t.id) 
    AS 'column8', 

(SELECT c.name FROM syscolumns c INNER JOIN sysindexkeys k 
    ON k.indid = i.indid 
     AND c.colid = k.colid 
     AND c.id = t.id 
     AND k.keyno = 9 
     AND k.id = t.id) 
    AS 'column9', 

(SELECT c.name FROM syscolumns c INNER JOIN sysindexkeys k 
    ON k.indid = i.indid 
     AND c.colid = k.colid 
     AND c.id = t.id 
     AND k.keyno = 10 
     AND k.id = t.id) 
    AS 'column10', 

FROM sysobjects t 
    INNER JOIN sysindexes i ON i.id = t.id 
    INNER JOIN sysobjects it ON it.parent_obj = t.id AND it.name = i.name 

WHERE it.xtype = 'PK' 
ORDER BY t.name, i.name 
+0

Pour une raison quelconque, j'obtiens une erreur sur les sous-requêtes retournant plusieurs valeurs. J'ai essayé de commenter chacune des sous-requêtes pour voir si je pouvais le faire pointer, mais elles semblent toutes échouer sur la même table, qui n'a qu'un seul champ dans son index. Des idées pour lesquelles cela arriverait? – Marshall

+0

J'ai trouvé que le problème était lorsqu'une fonction de table était listée. Je ne sais pas pourquoi, mais le champ compte pour une colonne (c'est-à-dire colonne1) était 2. Ma solution était de changer la clause WHERE finale en "WHERE it.xtype = 'PK' AND t. [Type] = 'U'". – Marshall

+0

Je l'ai également fait en utilisant la fonction isnull sur chaque colonne pour éviter de voir 'NULL' dans mon jeu de résultats. Par exemple: , ISNULL ( (SELECT c.name DE syscolumns c INNER JOIN sysindexkeys k = ON k.indid i.indid ET c.colid = k.colid ET c.id = t.id ET k.keyno = 1 ET k.id = t.id), '' ) AS 'column1' – Marshall

5

J'aime la technique INFORMATION_SCHEMA, mais une autre, je l'ai utilisé est: exec table 'sp_pkeys

1

Merci Guy.

Avec une légère variation, je l'ai utilisé pour trouver toutes les clés primaires pour toutes les tables.

SELECT A.Name,Col.Column_Name from 
    INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab, 
    INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col , 
    (select NAME from dbo.sysobjects where xtype='u') AS A 
WHERE 
    Col.Constraint_Name = Tab.Constraint_Name 
    AND Col.Table_Name = Tab.Table_Name 
    AND Constraint_Type = 'PRIMARY KEY ' 
    AND Col.Table_Name = A.Name 
1
SELECT A.TABLE_NAME as [Table_name], A.CONSTRAINT_NAME as [Primary_Key] 
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS A, INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE B 
WHERE CONSTRAINT_TYPE = 'PRIMARY KEY' AND A.CONSTRAINT_NAME = B.CONSTRAINT_NAME 
4

--Ce est une autre version modifiée qui est aussi un exemple de coopération liée Interrogation

SELECT TC.TABLE_NAME as [Table_name], TC.CONSTRAINT_NAME as [Primary_Key] 
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC 
INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CCU 
ON TC.CONSTRAINT_NAME = CCU.CONSTRAINT_NAME 
WHERE TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND 
TC.TABLE_NAME IN 
(SELECT [NAME] AS [TABLE_NAME] FROM SYS.OBJECTS 
WHERE TYPE = 'U') 
3

Cela devrait énumérer toutes les contraintes (clé primaire et les clés étrangères) et à la fin du nom de la table de vente de requête

/* CAST IS DONE , SO THAT OUTPUT INTEXT FILE REMAINS WITH SCREEN LIMIT*/ 
WITH ALL_KEYS_IN_TABLE (CONSTRAINT_NAME,CONSTRAINT_TYPE,PARENT_TABLE_NAME,PARENT_COL_NAME,PARENT_COL_NAME_DATA_TYPE,REFERENCE_TABLE_NAME,REFERENCE_COL_NAME) 
AS 
(
SELECT CONSTRAINT_NAME= CAST (PKnUKEY.name AS VARCHAR(30)) , 
     CONSTRAINT_TYPE=CAST (PKnUKEY.type_desc AS VARCHAR(30)) , 
     PARENT_TABLE_NAME=CAST (PKnUTable.name AS VARCHAR(30)) , 
     PARENT_COL_NAME=CAST (PKnUKEYCol.name AS VARCHAR(30)) , 
     PARENT_COL_NAME_DATA_TYPE= oParentColDtl.DATA_TYPE,   
     REFERENCE_TABLE_NAME='' , 
     REFERENCE_COL_NAME='' 

FROM sys.key_constraints as PKnUKEY 
    INNER JOIN sys.tables as PKnUTable 
      ON PKnUTable.object_id = PKnUKEY.parent_object_id 
    INNER JOIN sys.index_columns as PKnUColIdx 
      ON PKnUColIdx.object_id = PKnUTable.object_id 
      AND PKnUColIdx.index_id = PKnUKEY.unique_index_id 
    INNER JOIN sys.columns as PKnUKEYCol 
      ON PKnUKEYCol.object_id = PKnUTable.object_id 
      AND PKnUKEYCol.column_id = PKnUColIdx.column_id 
    INNER JOIN INFORMATION_SCHEMA.COLUMNS oParentColDtl 
      ON oParentColDtl.TABLE_NAME=PKnUTable.name 
      AND oParentColDtl.COLUMN_NAME=PKnUKEYCol.name 
UNION ALL 
SELECT CONSTRAINT_NAME= CAST (oConstraint.name AS VARCHAR(30)) , 
     CONSTRAINT_TYPE='FK', 
     PARENT_TABLE_NAME=CAST (oParent.name AS VARCHAR(30)) , 
     PARENT_COL_NAME=CAST (oParentCol.name AS VARCHAR(30)) , 
     PARENT_COL_NAME_DATA_TYPE= oParentColDtl.DATA_TYPE,  
     REFERENCE_TABLE_NAME=CAST (oReference.name AS VARCHAR(30)) , 
     REFERENCE_COL_NAME=CAST (oReferenceCol.name AS VARCHAR(30)) 
FROM sys.foreign_key_columns FKC 
    INNER JOIN sys.sysobjects oConstraint 
      ON FKC.constraint_object_id=oConstraint.id 
    INNER JOIN sys.sysobjects oParent 
      ON FKC.parent_object_id=oParent.id 
    INNER JOIN sys.all_columns oParentCol 
      ON FKC.parent_object_id=oParentCol.object_id /* ID of the object to which this column belongs.*/ 
      AND FKC.parent_column_id=oParentCol.column_id/* ID of the column. Is unique within the object.Column IDs might not be sequential.*/ 
    INNER JOIN sys.sysobjects oReference 
      ON FKC.referenced_object_id=oReference.id 
    INNER JOIN INFORMATION_SCHEMA.COLUMNS oParentColDtl 
      ON oParentColDtl.TABLE_NAME=oParent.name 
      AND oParentColDtl.COLUMN_NAME=oParentCol.name 
    INNER JOIN sys.all_columns oReferenceCol 
      ON FKC.referenced_object_id=oReferenceCol.object_id /* ID of the object to which this column belongs.*/ 
      AND FKC.referenced_column_id=oReferenceCol.column_id/* ID of the column. Is unique within the object.Column IDs might not be sequential.*/ 

) 

select * from ALL_KEYS_IN_TABLE 
where 
    PARENT_TABLE_NAME in ('YOUR_TABLE_NAME') 
    or REFERENCE_TABLE_NAME in ('YOUR_TABLE_NAME') 
ORDER BY PARENT_TABLE_NAME,CONSTRAINT_NAME; 

Pour référence s'il vous plaît lire à travers - http://blogs.msdn.com/b/sqltips/archive/2005/09/16/469136.aspx

1

J'ai trouvé cela utile, donne une liste de tables avec une virgule séparée liste des colonnes, puis aussi une liste séparée par des virgules dont les uns sont la clé primaire

SELECT T.TABLE_SCHEMA, T.TABLE_NAME, 
STUFF((
    SELECT ', ' + C.COLUMN_NAME 
    FROM INFORMATION_SCHEMA.COLUMNS C 
     WHERE C.TABLE_SCHEMA = T.TABLE_SCHEMA 
     AND T.TABLE_NAME = C.TABLE_NAME 
     FOR XML PATH ('') 
    ), 1, 2, '') AS Columns, 
STUFF((
SELECT ', ' + C.COLUMN_NAME 
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE C 
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC 
    ON C.TABLE_SCHEMA = TC.TABLE_SCHEMA 
    AND C.TABLE_NAME = TC.TABLE_NAME 
    WHERE C.TABLE_SCHEMA = T.TABLE_SCHEMA 
    AND T.TABLE_NAME = C.TABLE_NAME 
    AND TC.CONSTRAINT_TYPE = 'PRIMARY KEY' 
    FOR XML PATH ('') 
), 1, 2, '') AS [Key] 
FROM INFORMATION_SCHEMA.TABLES T 
ORDER BY T.TABLE_SCHEMA, T.TABLE_NAME 
1

Celui-ci vous donne les colonnes qui sont PK.

SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = 'TableName' 
18

Il est pratique généralement recommandé maintenant d'utiliser les sys.* vues sur INFORMATION_SCHEMA dans SQL Server, de sorte que si vous envisagez de bases de données migration j'utiliser ceux-ci.Voici comment vous le feriez avec les sys.* vues:

SELECT 
    c.name AS column_name, 
    i.name AS index_name, 
    c.is_identity 
FROM sys.indexes i 
    inner join sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id 
    inner join sys.columns c ON ic.object_id = c.object_id AND c.column_id = ic.column_id 
WHERE i.is_primary_key = 1 
    and i.object_ID = OBJECT_ID('<schema>.<tablename>'); 
+1

Pour commander, ajoutez 'ORDER BY ic.key_ordinal ASC' à la requête –

11

C'est une solution qui utilise uniquement sys -Tableaux.

Il répertorie toutes les clés primaires dans la base de données. Il renvoie le schéma , le nom de la table, le nom de la colonne et l'correcte ordre de tri de la colonne pour chaque clé primaire.

Si vous voulez obtenir la clé primaire pour une table spécifique, vous devez filtrer sur SchemaName et TableName. À mon humble avis, cette solution est très générique et n'utilise aucun littéral de chaîne, donc elle fonctionnera sur n'importe quelle machine.

select 
    s.name as SchemaName, 
    t.name as TableName, 
    tc.name as ColumnName, 
    ic.key_ordinal as KeyOrderNr 
from 
    sys.schemas s 
    inner join sys.tables t on s.schema_id=t.schema_id 
    inner join sys.indexes i on t.object_id=i.object_id 
    inner join sys.index_columns ic on i.object_id=ic.object_id 
            and i.index_id=ic.index_id 
    inner join sys.columns tc on ic.object_id=tc.object_id 
          and ic.column_id=tc.column_id 
where i.is_primary_key=1 
order by t.name, ic.key_ordinal ; 
+1

J'aimerais pouvoir voter plus qu'une seule fois. Exactement ce dont j'avais besoin et juste à temps. – fqhv

1

Ci-dessous la liste requête clés primaires de table particulière:

SELECT DISTINCT 
    CONSTRAINT_NAME AS [Constraint], 
    TABLE_SCHEMA AS [Schema], 
    TABLE_NAME AS TableName 
FROM 
    INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
WHERE 
    TABLE_NAME = 'mytablename' 
0

Cette version affiche le schéma, le nom de la table et un ordre, séparées par des virgules liste des clés primaires. Object_Id() ne fonctionne pas pour les serveurs de liens, donc nous filtrons par le nom de la table. Sans le REPLACE (Si1.Column_Name, '', ''), il afficherait les balises xml d'ouverture et de fermeture de Column_Name sur la base de données sur laquelle je testais. Je ne suis pas sûr pourquoi la base de données a exigé un remplacement pour 'Column_Name' donc si quelqu'un sait alors s'il vous plaît commenter.

DECLARE @TableName VARCHAR(100) = ''; 
WITH Sysinfo 
    AS (SELECT Kcu.Table_Name 
      , Kcu.Table_Schema AS Schema_Name 
      , Kcu.Column_Name 
      , Kcu.Ordinal_Position 
     FROM [LinkServer].Information_Schema.Key_Column_Usage Kcu 
      JOIN [LinkServer].Information_Schema.Table_Constraints AS Tc ON Tc.Constraint_Name = Kcu.Constraint_Name 
     WHERE Tc.Constraint_Type = 'Primary Key') 
    SELECT   Schema_Name 
        ,Table_Name 
        , STUFF(
          (
          SELECT ', ' 
           , REPLACE(Si1.Column_Name, '', '') 
          FROM Sysinfo Si1 
          WHERE Si1.Table_Name = Si2.Table_Name 
          ORDER BY Si1.Table_Name 
            , Si1.Ordinal_Position 
          FOR XML PATH('') 
         ), 1, 2, '') AS Primary_Keys 
    FROM Sysinfo Si2 
    WHERE Table_Name = CASE 
         WHEN @TableName NOT IN('', 'All') 
         THEN @TableName 
         ELSE Table_Name 
        END 
    GROUP BY Si2.Table_Name, Si2.Schema_Name; 

Et le même schéma en utilisant la requête de George:

DECLARE @TableName VARCHAR(100) = ''; 
WITH Sysinfo 
    AS (SELECT S.Name AS Schema_Name 
      , T.Name AS Table_Name 
      , Tc.Name AS Column_Name 
      , Ic.Key_Ordinal AS Ordinal_Position 
     FROM [LinkServer].Sys.Schemas S 
      JOIN [LinkServer].Sys.Tables T ON S.Schema_Id = T.Schema_Id 
      JOIN [LinkServer].Sys.Indexes I ON T.Object_Id = I.Object_Id 
      JOIN [LinkServer].Sys.Index_Columns Ic ON I.Object_Id = Ic.Object_Id 
                 AND I.Index_Id = Ic.Index_Id 
      JOIN [LinkServer].Sys.Columns Tc ON Ic.Object_Id = Tc.Object_Id 
                AND Ic.Column_Id = Tc.Column_Id 
     WHERE I.Is_Primary_Key = 1) 
    SELECT   Schema_Name 
        ,Table_Name 
        , STUFF(
          (
          SELECT ', ' 
           , REPLACE(Si1.Column_Name, '', '') 
          FROM Sysinfo Si1 
          WHERE Si1.Table_Name = Si2.Table_Name 
          ORDER BY Si1.Table_Name 
            , Si1.Ordinal_Position 
          FOR XML PATH('') 
         ), 1, 2, '') AS Primary_Keys 
    FROM Sysinfo Si2 
    WHERE Table_Name = CASE 
         WHEN @TableName NOT IN('', 'All') 
         THEN @TableName 
         ELSE Table_Name 
        END 
    GROUP BY Si2.Table_Name, Si2.Schema_Name; 
0

sys.objects table contient, pour chaque rangée définie par l'utilisateur, objet scope schéma.

Les contraintes créées comme clé primaire ou d'autres seront l'objet et Nom de la table sera le parent_object

Query sys.objects et recueillir Ids de type requis

declare @TableName nvarchar(50)='TblInvoice' -- your table name 
declare @TypeOfKey nvarchar(50)='PK' -- For Primary key 

SELECT Name FROM sys.objects 
WHERE type = @TypeOfKey 
AND parent_object_id = OBJECT_ID (@TableName) 
de l'objet
1

Je dis une technique simple que je suis

SP_HELP 'table_name' 

exécuter ce code en tant que requête. Mentionnez le nom de votre table à la place de nom_table pour lequel vous voulez connaître la clé primaire (ne pas oublier les guillemets simples). Le résultat montrera comme l'image jointe.Espérons que cela vous aidera

enter image description here

+0

Assurez-vous d'entourer votre nom de table entre guillemets simples ou la commande ne fonctionnera pas! – Shadoninja

0

Puis-je suggérer une réponse simple plus précise à la question initiale ci-dessous

SELECT 
KEYS.table_schema, KEYS.table_name, KEYS.column_name, KEYS.ORDINAL_POSITION 
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE keys 
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS CONS 
    ON cons.TABLE_SCHEMA = keys.TABLE_SCHEMA 
    AND cons.TABLE_NAME = keys.TABLE_NAME 
    AND cons.CONSTRAINT_NAME = keys.CONSTRAINT_NAME 
WHERE cons.CONSTRAINT_TYPE = 'PRIMARY KEY' 

Notes:

  1. Certaines des réponses ci-dessus manque une filtre pour juste clé primaire colonnes!
  2. J'utilise ci-dessous dans un CTE à se joindre à une plus grande colonne liste pour fournir les métadonnées d'une source pour alimenter BIML génération de tables de mise en scène et le code SSIS
Questions connexes