2008-09-18 99 views

回答

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-这不一定列出字段*为了*。如果您需要以其特定顺序排列的列,请参见类似问题的答案:http://stackoverflow.com/a/3942921/18511 – Kip 2013-02-04 03:17:16

+6

实际上,我相信您还必须通过Schema进行约束,对吧?所以,你需要添加“And COL.TABLE_SCHEMA ='<你的模式名称>'”。 – DavidStein 2013-05-17 15:56:41

+0

如果上述查询返回3行“a”,“b”和“c”(按该顺序),那么我的表有一个主复合键“abc”? – 2017-07-22 19:16:30

0

系统存储过程sp_help会为您提供信息。执行以下语句:

execute sp_help table_name 
5

是使用MS SQL Server,您可以执行以下操作:

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

如果你想要一个特定的表,您也可以对TABLE_NAME列筛选。

+3

此只列出关键,它不会列出在关键 – Kip 2013-01-30 21:35:56

+0

这是关闭的权利开始,但需要与INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE被连接在由盖伊星巴克的答案列。 – bstrong 2016-01-05 20:26:25

0

试试这个:

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

出于某种原因,我在返回多个值的子查询中出现错误。我试着评论每个子查询,看看我是否可以指出它,但它们似乎都在同一张桌子上失败,在同一张桌子上只有一个字段在索引中。任何想法为什么会发生? – Marshall 2011-09-09 13:39:56

5

我喜欢INFORMATION_SCHEMA技术,但另一个我用的是: EXEC sp_pkeys '表'

1

感谢盖伊。

我用它来查找所有表的所有主键。

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

- 这是另一种改进版本,这也是对合作相关的一个例子查询

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

这应当列出所有的约束(主键和外键),并在查询放表名的末尾

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

仅供参考,请阅读直通 - http://blogs.msdn.com/b/sqltips/archive/2005/09/16/469136.aspx

1

我发现这个很有用,给出了一列用逗号分隔列表的列表,然后还有一个逗号分隔列表,其中主键是哪个列表

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

这一个给你的是PK列。

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

它通常建议的做法,现在使用了INFORMATION_SCHEMAsys.*观点在SQL Server中,所以,除非你是在迁移的数据库我会用那些计划。这里是你将如何与sys.*观点做到这一点:

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>'); 
11

这是只使用SYS -tables的解决方案。

它列出了数据库中的所有主键。它为每个主键返回架构,表名称,列名称和正确的列排序顺序

如果你想获得一个特定的表的主键,那么你需要在SchemaNameTableName过滤。

恕我直言,这个解决方案是非常通用的,不使用任何字符串文字,因此它可以在任何机器上运行。

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

下面的查询将列出主键特定表

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

这个版本显示模式,表名和一个有序的,以逗号分隔的主键的列表。 Object_Id()不适用于链接服务器,所以我们按表名进行过滤。

没有REPLACE(Si1.Column_Name,'','')它会在我测试的数据库上显示Column_Name的xml打开和关闭标记。我不知道为什么数据库需要替换'Column_Name',所以如果有人知道,那么请评论。

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; 

并采用乔治的查询相同的模式:

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中表包含每个用户定义的架构范围内的对象 一行。像主键或其他人创建

约束将是对象和 表名称将是parent_object

查询sys.objects中,并收集所需的对象的IDS类型

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) 
1

我在讲一个简单的技术,我遵循

SP_HELP 'table_name' 

将此代码作为查询运行。在您希望知道主键的table_name位置提及您的表名(不要忘记单引号)。结果将显示像附加的图像。希望这将有助于你

enter image description here

0

可能,我建议如下

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' 

注意更准确的简单的答案原来的问题:

  1. 有些答案的上方缺少过滤只是主键 列!
  2. 我使用下面的CTE加入到更大的柱 列表从源提供所述元数据喂BIML代临时表的和SSIS代码