2010-10-14 34 views
97

thể trùng lặp:
How do you list the primary key of a SQL Server table?SQL Server: Nhận khóa chính bảng sử dụng truy vấn sql

Tôi muốn để có được khóa chính một bảng cụ thể bằng cách sử dụng truy vấn SQL cho SQL Server cơ sở dữ liệu.

Trong MySQL Tôi đang sử dụng truy vấn sau đây để có được khóa chính bảng:

SHOW KEYS FROM tablename WHERE Key_name = 'PRIMARY' 

là gì tương đương với truy vấn trên cho SQL Server?.

Nếu có truy vấn sẽ hoạt động cho cả MySQLSQL Server thì đó sẽ là trường hợp lý tưởng.

+1

Hãy cẩn thận khi sử dụng INFORMATION_SCHEMA.Views vì họ không thể tin cậy trở CONSTRAINT_SCHEMA và TABLE_SCHEMA (xem, ví dụ: http://msdn.microsoft.com/en-us /library/ms181757.aspx) Để thảo luận về vấn đề này, hãy kiểm tra chủ đề MSDN này http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/732bd071-2c1f-4c23-9215-4ff3822c63c3 – Naomi

Trả lời

49

Tìm thấy một số khác:

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; 

Tôi đã thử nghiệm này trên SQL Server 2003/2005

+4

Điều quan trọng về việc này là nó cung cấp cho bạn các trường PK ** theo thứ tự **. Đôi khi nó quan trọng! – Kip

+0

Một phiên bản khác đặt chúng theo thứ tự trong danh sách được phân tách bằng dấu phẩy ở đây: http://stackoverflow.com/a/42985271/1339704 – Soenhay

+0

Sử dụng 'information_schema' (trái ngược với' sys.'views) luôn là một ý tưởng tốt vì nó là tiêu chuẩn chính thức và được thực hiện trong một vài hệ thống cơ sở dữ liệu khác. – Jakub

9

Từ bộ nhớ, nó là một trong hai này

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

hay này ..

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

Tôi nghĩ rằng một trong số họ có lẽ nên làm việc tùy thuộc vào cách dữ liệu được lưu trữ nhưng tôi sợ tôi có không có quyền truy cập vào SQL để thực sự xác minh giống nhau.

47

Sử dụng SQL SERVER 2005, bạn có thể thử

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 

Tìm thấy tại SQL SERVER – 2005 – Find Tables With Primary Key Constraint in Database

+0

Nơi sẽ đặt tên bảng mong muốn của tôi (khóa chính bắt buộc cho) trong truy vấn ở trên? – Awan

+0

Rất đẹp vì nó hiển thị chúng theo thứ tự xuất hiện thay vì A-Z –

+0

Truy vấn này chạy nhanh hơn rất nhiều so với câu trả lời được bỏ phiếu nhiều nhất trên cơ sở dữ liệu nhỏ và trống của tôi. – Gobe

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

này sẽ làm việc trong sql 2005

+0

Nếu bạn đăng mã hoặc XML, ** vui lòng ** làm nổi bật các dòng đó trong trình soạn thảo văn bản và nhấp vào nút "mã" (101 010) trên thanh công cụ trình soạn thảo để định dạng và cú pháp tô sáng nó! –

+1

Ngoài ra, trong SQL Server 2005 trở lên, bạn nên sử dụng khung nhìn danh mục 'sys' và ngừng sử dụng bảng' sysobjects' kế thừa. Vì vậy, trong trường hợp của bạn, hãy sử dụng 'sys.tables' và' sys.columns' và các khung nhìn danh mục sys khác. –

3

Mã này tôi sẽ cung cấp cho bạn hoạt động và lấy không chỉ có các khóa, nhưng rất nhiều dữ liệu từ một bảng trong SQL Server. Được kiểm tra trong SQL Server 2k5/2k8, dunno khoảng 2k. Thưởng thức!

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 

Bạn chỉ có thể sử dụng phần chính, nhưng tôi nghĩ phần còn lại có thể trở nên hữu ích. Trân trọng, David

123

Tôi cũng tìm thấy một số khác cho 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

Nó không chạy trên SQL Server 2005. Tôi đã thêm một câu trả lời hữu ích cho cả SQL Server 2003 và SQL Server 2005. – Awan

+2

Không biết tại sao, nhưng OBJECTPROPERTY (OBJECT_ID (constraint_name), 'IsPrimaryKey') trả về NULL trong của tôi trường hợp. Giải pháp dưới đây hoạt động tốt. Có lẽ giải pháp của bạn không hoạt động đối với PK phức tạp (2 cột trở lên). – nZeus

+3

Nếu bạn đang gặp vấn đề tương tự, hàm đối tượng thuộc tính sẽ trả về null vì hàm id đối tượng sẽ trả về null nếu ràng buộc được gắn vào một đối tượng không có trong lược đồ dbo. Bạn phải ghép nối lược đồ ràng buộc với tên ràng buộc bên trong của hàm id đối tượng. Hy vọng điều này sẽ giúp người khác. – jwhaley58

1

Nó cũng là (Transact-SQL) ... theo 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

này nên liệt kê tất cả những hạn chế và cuối cùng bạn có thể đặt bộ lọc của bạn

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

Để tham khảo, vui lòng đọc qua - 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%' 

ĐÂU
{} DatabaseName = cơ sở dữ liệu của bạn từ máy chủ của bạn VÀ
{TABLENAME} = tên bảng của bạn từ đó bạn muốn xem các khóa chính.

LƯU Ý: nhập tên cơ sở dữ liệu và tên bảng của bạn không có dấu ngoặc vuông.

2

Hãy nhớ rằng nếu bạn muốn lấy trường chính xác, bạn cần đặt TABLE_NAME và TABLE_SCHEMA vào điều kiện.

giải pháp này nên làm việc:

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

CONSTRAINT_NAME không phải lúc nào cũng là 'CHÍNH' – frostymarvelous

Các vấn đề liên quan