Simple question, comment lister la clé primaire d'une table avec T-SQL? Je sais comment obtenir des index sur une table, mais ne me souviens pas comment obtenir le PK.Comment répertoriez-vous la clé primaire d'une table SQL Server?
Répondre
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>'
La procédure stockée système sp_help
vous donnera les informations. Exécutez l'instruction suivante:
execute sp_help table_name
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.
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'
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
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
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
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
J'aime la technique INFORMATION_SCHEMA, mais une autre, je l'ai utilisé est: exec table 'sp_pkeys
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
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
--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')
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
Voici une beaucoup plus simple de la question: Get table primary key using sql query:
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA+'.'+CONSTRAINT_NAME), 'IsPrimaryKey') = 1
AND TABLE_NAME = '<your table name>'
Il utilise KEY_COLUMN_USAGE
pour déterminer les contraintes d'une table donnée
utilise ensuite OBJECTPROPERTY(id, 'IsPrimaryKey')
pour déterminer si chacun est une clé primaire
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
Celui-ci vous donne les colonnes qui sont PK.
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = 'TableName'
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>');
Pour commander, ajoutez 'ORDER BY ic.key_ordinal ASC' à la requête –
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 ;
J'aimerais pouvoir voter plus qu'une seule fois. Exactement ce dont j'avais besoin et juste à temps. – fqhv
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'
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;
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
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
Assurez-vous d'entourer votre nom de table entre guillemets simples ou la commande ne fonctionnera pas! – Shadoninja
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:
- Certaines des réponses ci-dessus manque une filtre pour juste clé primaire colonnes!
- 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
- 1. Sql Type de données pour la clé primaire - SQL Server?
- 2. SQL Server 2008: trouvez la clé primaire/étrangère dans la table?
- 3. comment modifier table de clé primaire composite
- 4. Blocage SQL Server 2005 sur la clé
- 5. Obtenir le nom de la clé primaire de la table
- 6. SQL Server: table de baisse clé primaire, sans connaître son nom
- 7. SqlBulkCopy dans la table avec la clé primaire composite
- 8. Comment puis-je obtenir la dernière clé primaire insérée?
- 9. Clé primaire Croissant et décroissant
- 10. Clé primaire de la ligne insérée jdbc?
- 11. Récupère la clé primaire d'une nouvelle entrée
- 12. clé primaire entière pour la réplication
- 13. Ignorer les conflits de clé primaire avec la copie SQL
- 14. Table SQL - Temp: Stockage de toutes les colonnes dans la table temporaire par rapport à la clé primaire
- 15. La clé unique Sql Server est-elle également un index?
- 16. Comment puis-je faire une clé primaire
- 17. Clé primaire composée
- 18. Sql Server 2005 violation de clé primaire sur une colonne d'identité
- 19. Modifier chaque enregistrement dans une table sans clé primaire?
- 20. L'exigence de clé primaire LINQ to SQL échoue
- 21. Subsonic erreur clé primaire
- 22. SqlServer créer une table avec MySQL comme auto_increment clé primaire
- 23. Beaucoup-plusieurs sans clé primaire
- 24. LINQ to SQL: Insérer une clé primaire sans identité
- 25. Question SQL rapide: Syntaxe correcte pour créer une table avec une clé primaire dans H2?
- 26. SQL Server: Comment indexer au mieux une table N-N?
- 27. NHibernate avec la clé primaire et les relations
- 28. Récupère la clé primaire de la requête groupée par SQL en utilisant PostgreSQL
- 29. Clé cd SQL Server 2005
- 30. Comment puis-je insérer dans une table et récupérer la valeur de clé primaire?
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
En fait, je crois que vous devez également contraindre par Schema, non? Donc, vous devez ajouter "Et COL.TABLE_SCHEMA = ''". –
DavidStein
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'? –