2010-10-14 28 views
97

Powiel możliwe:
How do you list the primary key of a SQL Server table?SQL Server: Zdobądź klucz podstawowy tabeli za pomocą kwerendy SQL

Chcę uzyskać klucz podstawowy konkretnej tabeli w użyciu kwerendy SQL dla SQL Server bazy danych.

W MySQL używam następującą kwerendę, aby uzyskać klucz podstawowy tabeli:

SHOW KEYS FROM tablename WHERE Key_name = 'PRIMARY' 

Co jest odpowiednikiem powyższego zapytania do SQL Server?.

Jeśli jest zapytanie, które będzie działać zarówno MySQL i SQL Server wtedy będzie idealnym przypadku.

+1

Bądź ostrożny używając INFORMATION_SCHEMA.Views ponieważ nie można wiarygodnie powrócić CONSTRAINT_SCHEMA i TABLE_SCHEMA (patrz, na przykład: http://msdn.microsoft.com/en-us /library/ms181757.aspx) Aby porozmawiać o tym problemie, sprawdź ten wątek MSDN http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/732bd071-2c1f-4c23-9215-4ff3822c63c3 – Naomi

Odpowiedz

49

Znaleziono kolejny:

SELECT KU.table_name as TABLENAME,column_name as PRIMARYKEYCOLUMN 
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC 
INNER JOIN 
    INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU 
      ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND 
      TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME AND 
      KU.table_name='yourTableName' 
ORDER BY KU.TABLE_NAME, KU.ORDINAL_POSITION; 

ja testowałem to na SQL Server 2003/2005

+4

Co jest ważne w tym przypadku, to daje pola PK ** w porządku **. Czasami to ma znaczenie! – Kip

+0

Inna wersja, która umieszcza je w porządku na liście oddzielonej przecinkami, znajduje się tutaj: http://stackoverflow.com/a/42985271/1339704 – Soenhay

+0

Używanie 'information_schema' (w przeciwieństwie do' sys.'views) jest zawsze dobrym pomysłem, ponieważ jest oficjalnym standardem i jest implementowany w kilku innych systemach baz danych. – Jakub

9

z pamięci, to albo to

SELECT * FROM sys.objects 
WHERE type = 'PK' 
AND object_id = OBJECT_ID ('tableName') 

czy to ..

SELECT * FROM sys.objects 
WHERE type = 'PK' 
AND parent_object_id = OBJECT_ID ('tableName') 

Myślę, że jednym z nich prawdopodobnie powinien działać w zależności od sposobu, w jaki dane są przechowywane ale obawiam się, że mają brak dostępu do SQL w celu faktycznego zweryfikowania tego samego.

47

Korzystanie z SQL Server 2005, można spróbować

SELECT i.name AS IndexName, 
     OBJECT_NAME(ic.OBJECT_ID) AS TableName, 
     COL_NAME(ic.OBJECT_ID,ic.column_id) AS ColumnName 
FROM sys.indexes AS i INNER JOIN 
     sys.index_columns AS ic ON i.OBJECT_ID = ic.OBJECT_ID 
           AND i.index_id = ic.index_id 
WHERE i.is_primary_key = 1 

Znaleziony w SQL SERVER – 2005 – Find Tables With Primary Key Constraint in Database

+0

Gdzie umieści żądaną nazwę tabeli (klucz podstawowy wymagany) w powyższym zapytaniu? – Awan

+0

Bardzo ładne, ponieważ wyświetla je w kolejności występowania zamiast A-Z –

+0

To zapytanie działało o wiele szybciej niż najbardziej uprzywilejowana odpowiedź w mojej małej i pustej bazie danych. – Gobe

4
select * 
from sysobjects 
where xtype='pk' and 
    parent_obj in (select id from sysobjects where name='tablename') 

to będzie działać w SQL 2005

+0

Jeśli umieścisz kod lub XML, ** proszę ** podświetl te linie w edytorze tekstu i kliknij przycisk "kod" (101 010) na pasku narzędzi edytora, aby ładnie sformatować i podświetlić składnię! –

+1

Ponadto, w SQL Server 2005 i nowszych, zalecane jest użycie widoków katalogu 'sys' i zaprzestanie używania starszej tabeli' sysobjects'. Tak więc w twoim przypadku użyj 'sys.tables' i' sys.columns' oraz innych widoków katalogu sys. –

3

Kodeksu dam Ci działa i nie pobiera tylko klucze, ale dużo danych z tabeli w SQL Server. Jest testowany w SQL Server 2k5/2k8, dunno około 2k. Cieszyć się!

SELECT DISTINCT 
    sys.tables.object_id AS TableId, 
    sys.columns.column_id AS ColumnId, 
    sys.columns.name AS ColumnName, 
    sys.types.name AS TypeName, 
    sys.columns.precision AS NumericPrecision, 
    sys.columns.scale AS NumericScale, 
    sys.columns.is_nullable AS IsNullable, 
    ( SELECT 
      COUNT(column_name) 
     FROM 
      INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE 
     WHERE 
      TABLE_NAME = sys.tables.name AND 
      CONSTRAINT_NAME = 
       ( SELECT 
        constraint_name 
        FROM 
         INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
        WHERE 
         TABLE_NAME = sys.tables.name AND      
         constraint_type = 'PRIMARY KEY' AND 
         COLUMN_NAME = sys.columns.name 
       ) 
    ) AS IsPrimaryKey, 
    sys.columns.max_length/2 AS CharMaxLength /*BUG*/ 
FROM 
    sys.columns, sys.types, sys.tables 
WHERE 
    sys.tables.object_id = sys.columns.object_id AND 
    sys.types.system_type_id = sys.columns.system_type_id AND 
    sys.types.user_type_id = sys.columns.user_type_id AND 
    sys.tables.name = 'TABLE' 
ORDER BY 
    IsPrimaryKey 

Możesz użyć tylko klucza głównego, ale myślę, że reszta może się przydać. poważaniem, David

123

Znalazłem też inny dla SQL Server:

SELECT COLUMN_NAME 
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + QUOTENAME(CONSTRAINT_NAME)), 'IsPrimaryKey') = 1 
AND TABLE_NAME = 'TableName' AND TABLE_SCHEMA = 'Schema' 
+0

Nie działa na SQL Server 2005. Dodałem kolejną odpowiedź, która jest przydatna zarówno dla SQL Server 2003 i SQL Server 2005. – Awan

+2

Nie wiem dlaczego, ale OBJECTPROPERTY (OBJECT_ID (constraint_name), "IsPrimaryKey") zwraca NULL w moim walizka. Poniższe rozwiązanie działa dobrze. Może twoje rozwiązanie nie działa dla złożonych PK (2 i więcej kolumn). – nZeus

+3

Jeśli cierpisz na ten sam problem, który miałem, funkcja właściwości obiektu zwraca null, ponieważ funkcja id obiektu zwróci wartość null, jeśli ograniczenie jest dołączone do obiektu spoza schematu dbo. Konieczne jest połączenie schematu wiązań z nazwą ograniczenia wewnątrz funkcji id obiektu. Mam nadzieję, że to pomoże komuś innemu. – jwhaley58

1

Jest również (Transact-SQL) ... według BOL.

-- exec sp_serveroption 'SERVER NAME', 'data access', 'true' --execute once 

EXEC sp_primarykeys @table_server = N'server_name', 
    @table_name = N'table_name', 
    @table_catalog = N'db_name', 
    @table_schema = N'schema_name'; --frequently 'dbo' 
4

ten powinien zawierać wszystkie ograniczenia i na koniec można umieścić swoje filtry

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

Aby uzyskać więcej informacji przeczytaj - http://blogs.msdn.com/b/sqltips/archive/2005/09/16/469136.aspx

5
SELECT COLUMN_NAME FROM {DATABASENAME}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
WHERE TABLE_NAME LIKE '{TABLENAME}' AND CONSTRAINT_NAME LIKE 'PK%' 

GDZIE
{databasename} = bazę danych z serwera i
{TableName} = swoją nazwę tabeli, z którego chcesz zobaczyć klucz podstawowy.

UWAGA: wprowadź nazwę bazy danych i nazwę tabeli bez nawiasów.

2

Należy pamiętać, że jeśli chcesz uzyskać dokładne pole podstawowe, musisz ustawić TABLE_NAME i TABLE_SCHEMA w tym stanie.

rozwiązanie to powinno działać:

select COLUMN_NAME from information_schema.KEY_COLUMN_USAGE 
where CONSTRAINT_NAME='PRIMARY' AND TABLE_NAME='TABLENAME' 
AND TABLE_SCHEMA='DATABASENAME' 
+1

CONSTRAINT_NAME nie zawsze jest "PODSTAWOWY" – frostymarvelous

Powiązane problemy