Как вы перечисляете первичный ключ таблицы SQL Server? - PullRequest
83 голосов
/ 18 сентября 2008

Простой вопрос, как вы перечисляете первичный ключ таблицы с T-SQL? Я знаю, как получить индексы для таблицы, но не могу вспомнить, как получить PK.

Ответы [ 24 ]

126 голосов
/ 18 сентября 2008
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>'
23 голосов
/ 10 сентября 2015

Как правило, сейчас рекомендуется использовать sys.* просмотры над INFORMATION_SCHEMA в 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>');
17 голосов
/ 16 мая 2016

Это решение, которое использует только sys -таблицы.

В нем перечислены все первичные ключи в базе данных. Он возвращает схему, имя таблицы, имя столбца и правильный порядок сортировки столбцов для каждого первичного ключа.

Если вы хотите получить первичный ключ для конкретной таблицы, вам нужно отфильтровать по SchemaName и TableName.

ИМХО, это решение очень универсальное и не использует строковые литералы, поэтому оно будет работать на любом компьютере.

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 ;
7 голосов
/ 04 июня 2014

Вот еще один способ из вопроса получить первичный ключ таблицы с помощью SQL-запроса :

SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA+'.'+CONSTRAINT_NAME), 'IsPrimaryKey') = 1
  AND TABLE_NAME = '<i><your table name></i>'

Используется KEY_COLUMN_USAGE для определения ограничений для данной таблицы
Затем использует OBJECTPROPERTY(<i>id</i>, 'IsPrimaryKey'), чтобы определить, является ли каждый первичным ключом

6 голосов
/ 07 октября 2008

Мне нравится метод INFORMATION_SCHEMA, но я использовал другой: exec sp_pkeys 'table'

6 голосов
/ 18 сентября 2008

При использовании MS SQL Server вы можете делать следующее:

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

Вы также можете фильтровать по столбцу table_name, если вы хотите конкретную таблицу.

4 голосов
/ 26 сентября 2011

- это еще одна модифицированная версия, которая также является примером для совместного запроса

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 голосов
/ 04 апреля 2013

Здесь должны быть перечислены все ограничения (первичный ключ и внешние ключи) и в конце запроса указано имя таблицы

/* 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 голос
/ 19 июня 2015

Я нашел это полезным, дает список таблиц с отдельным списком столбцов через запятую, а затем также отдельный список запятых, из которых первичный ключ является

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 голос
/ 26 сентября 2011
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...