ฉันจะค้นหาข้อ จำกัด ของคีย์ต่างประเทศที่อ้างอิงตารางใน SQL Server ได้อย่างไร


122

ฉันพยายามวางโต๊ะ แต่ได้รับข้อความต่อไปนี้:

ข่าวสารเกี่ยวกับ 3726 ระดับ 16 สถานะ 1 บรรทัดที่ 3
ไม่สามารถวางออบเจ็กต์ 'dbo.UserProfile' ได้เนื่องจากถูกอ้างอิงโดยข้อ จำกัด ของคีย์ต่างประเทศ
ข่าวสารเกี่ยวกับ 2714 ระดับ 16 สถานะ 6 บรรทัดที่ 2
มีออบเจ็กต์ชื่อ 'UserProfile' อยู่ในฐานข้อมูลแล้ว

ฉันมองไปรอบ ๆ ด้วย SQL Server Management Studio แต่ฉันไม่พบข้อ จำกัด ฉันจะค้นหาข้อ จำกัด ของคีย์ต่างประเทศได้อย่างไร


2
ฉันชอบ sp_help 'dbo.TableName' ดูวิธีเพิ่มเติมได้ที่นี่: stackoverflow.com/questions/483193/…
Mark Boltuc

2
Worth noticing:คำตอบโดย @LittleSweetSeas จะส่งคืนข้อมูลเกี่ยวกับคีย์ต่างประเทศสำหรับตารางอ้างอิงที่กำหนดอย่างไรก็ตามรายละเอียดคำตอบของ @Gayathri-Varma สำหรับตารางหลักที่ระบุ ทั้งสองมีประโยชน์ในบริบทที่แตกต่างกันและทั้งคู่ชนะการแข่งขันของตัวเอง :-)
Izhar Aazmi

คำตอบ:


225

นี่คือ:

SELECT 
   OBJECT_NAME(f.parent_object_id) TableName,
   COL_NAME(fc.parent_object_id,fc.parent_column_id) ColName
FROM 
   sys.foreign_keys AS f
INNER JOIN 
   sys.foreign_key_columns AS fc 
      ON f.OBJECT_ID = fc.constraint_object_id
INNER JOIN 
   sys.tables t 
      ON t.OBJECT_ID = fc.referenced_object_id
WHERE 
   OBJECT_NAME (f.referenced_object_id) = 'YourTableName'

ด้วยวิธีนี้คุณจะได้รับตารางอ้างอิงและชื่อคอลัมน์

แก้ไขเพื่อใช้ sys.tables แทน sys.objects ทั่วไปตามคำแนะนำความคิดเห็น ขอบคุณ marc_s


คุณควรใช้สิ่งที่เน้นsys.tablesมากกว่าsys.objects
marc_s

@marc_s: ขอบคุณ แต่คุณสามารถโพสต์ตัวอย่างได้หรือไม่? AFAIK ใน sys.tables ฉันไม่มีข้อมูลอ้างอิง FK
LittleSweetSeas

3
สิ่งที่ฉันหมายถึง: เพียงแค่แทนที่INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_idด้วยINNER JOIN sys.tables t ON t.OBJECT_ID = fc.referenced_object_id
marc_s

@LittleSweetSeas ฉันเรียกใช้แบบสอบถามข้างต้นแล้ว แต่ฉันยังไม่ได้รับ object_name และชื่อคอลัมน์สำหรับตารางที่มีข้อ จำกัด ของคีย์ต่างประเทศ
Smart003

คุณสามารถเพิ่มข้อมูลที่คุณเลือกได้ด้วยข้อมูลเพิ่มเติมเล็กน้อย: SELECT f.name ConstraintName, f.type_desc ConstraintType, OBJECT_NAME (f.parent_object_id) ConstrainedTable, COL_NAME (fc.parent_object_id, fc.parent_column_id) ConstrainedColumn, OBJECT_NAME (f.referenced_id) , COL_NAME (fc.referenced_object_id, fc.referenced_column_id) ReferencedColumn
DocOc

75

อีกวิธีหนึ่งคือการตรวจสอบผลลัพธ์ของ

sp_help 'TableName'

(หรือเพียงแค่เน้นชื่อ TableName ที่ยกมาและตั้ง ALT + F1)

เมื่อเวลาผ่านไปฉันก็ตัดสินใจที่จะปรับแต่งคำตอบของฉัน ด้านล่างนี้คือภาพหน้าจอของผลลัพธ์ที่sp_helpให้ A ได้ใช้ AdventureWorksDW2012 DB สำหรับตัวอย่างนี้ มีข้อมูลดีๆมากมายที่นั่นและสิ่งที่เรากำลังมองหาอยู่ท้ายสุด - เน้นด้วยสีเขียว:

ใส่คำอธิบายภาพที่นี่


3
+1 สิ่งนี้ให้ข้อมูลที่เป็นประโยชน์มากมายและแสดงคีย์ต่างประเทศที่ด้านล่างของเอาต์พุต
Hux

1
สิ่งนี้ทำให้ฉันมีข้อมูลมากมายในบรรทัดโค้ดที่น้อยที่สุด
Rennish Joseph

เกรียนแบบนี้เด็ดสุด! เอาชนะ Ctl-R โดยสมบูรณ์เพื่อรีเฟรชสคีมา!
Mr. Young

รีเฟรชแคช InteliSense ในเครื่อง = Ctrl + Shift + R; Ctrl + R = แสดง / ซ่อนบานหน้าต่างผลลัพธ์ (หรืออย่างน้อยก็เป็นค่าเริ่มต้นของฉันสำหรับ SSMS2008 และ SSMS2014)
Vladislav

44

ลองทำตามนี้

SELECT
  object_name(parent_object_id) ParentTableName,
  object_name(referenced_object_id) RefTableName,
  name 
FROM sys.foreign_keys
WHERE parent_object_id = object_id('Tablename')

1
สั้นและสวยแถมใช้ได้ด้วย! สิ่งเดียวคือnameค่าที่ส่งคืนคือชื่อภายใน (methinks) ไม่ใช่ชื่อคอลัมน์จริงในตารางหลัก วิธีใดในการแก้ไขปัญหานี้
Hamman Samuel

สิ่งที่ฉันเห็นที่นี่ParentTableNameมักจะเป็นเช่นเดียวกับที่ระบุ ' Tablename' ใน where clause (ถ้ารวม) นี่อาจเป็นความตั้งใจและจะมีประโยชน์มากขึ้นเมื่อสอบถามข้อมูลมากกว่าหนึ่งตาราง
Izhar Aazmi

28

ฉันพบว่าคำตอบนี้ค่อนข้างง่ายและใช้เคล็ดลับสำหรับสิ่งที่ฉันต้องการ: https://stackoverflow.com/a/12956348/652519

สรุปจากลิงค์ใช้แบบสอบถามนี้:

EXEC sp_fkeys 'TableName'

ง่ายและรวดเร็ว ฉันสามารถค้นหาตารางคีย์ต่างประเทศคอลัมน์ที่เกี่ยวข้องและชื่อคีย์ต่างประเทศทั้งหมด 15 ตารางได้อย่างรวดเร็ว

ตามที่ @mdisibio ระบุไว้ด้านล่างนี่คือลิงค์ไปยังเอกสารที่ให้รายละเอียดพารามิเตอร์ต่างๆที่สามารถใช้ได้: https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp- fkeys-SQL ของ


1
มีพารามิเตอร์อื่น ๆ อีกห้าตัวที่จะกรองสิ่งที่มีประโยชน์ที่สุดที่ควรทราบคือตัวที่สองที่คุณสามารถระบุสคีมาที่ไม่ใช่ค่าเริ่มต้นเช่นEXEC sp_fkeys 'Payroll', 'accounting'
mdisibio

8

ฉันใช้สคริปต์นี้เพื่อค้นหารายละเอียดทั้งหมดที่เกี่ยวข้องกับคีย์ต่างประเทศ ฉันใช้ INFORMATION.SCHEMA ด้านล่างนี้เป็นสคริปต์ SQL:

SELECT 
    ccu.table_name AS SourceTable
    ,ccu.constraint_name AS SourceConstraint
    ,ccu.column_name AS SourceColumn
    ,kcu.table_name AS TargetTable
    ,kcu.column_name AS TargetColumn
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu
    INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
        ON ccu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME 
    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu 
        ON kcu.CONSTRAINT_NAME = rc.UNIQUE_CONSTRAINT_NAME  
ORDER BY ccu.table_name

2
ฉันกำลังมองหาวิธีดูคอลัมน์ที่เป็นคีย์ต่างประเทศและตารางที่เกี่ยวข้องที่คอลัมน์นั้นอ้างอิงและสิ่งนี้ก็สรุปได้อย่างดี ขอบคุณ!
Nate Kindrew

สิ่งนี้ขาดคีย์ต่างประเทศในบางตารางของฉันในขณะที่คำตอบของ @LittleSweetSeasแสดงให้พวกเขาเห็น
Seafish

7

หากคุณต้องการไปผ่าน SSMS ในหน้าต่าง object explorer ให้คลิกขวาที่วัตถุที่คุณต้องการวางดูการอ้างอิง


7

นี่คือวิธีที่ดีที่สุดในการค้นหาความสัมพันธ์ของคีย์ต่างประเทศในฐานข้อมูลทั้งหมด

exec sp_helpconstraint 'Table Name'

และอีกวิธีหนึ่ง

select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME='Table Name'
--and left(CONSTRAINT_NAME,2)='FK'(If you want single key)

โซลูชันนี้exec sp_helpconstraint 'Table Name'เป็นโซลูชันเดียวที่ส่งคืนแถวใด ๆ ให้ฉัน อย่างไรก็ตามชื่อที่ไม่ถูกต้องเป็นคำพูดพล่อยๆ PRIMARY KEY (clustered) PK__org_soft__3213E83FE6B07364
ทอร์

5
SELECT 
    obj.name      AS FK_NAME,
    sch.name      AS [schema_name],
    tab1.name     AS [table],
    col1.name     AS [column],
    tab2.name     AS [referenced_table],
    col2.name     AS [referenced_column]
FROM 
     sys.foreign_key_columns fkc
INNER JOIN sys.objects obj
    ON obj.object_id = fkc.constraint_object_id
INNER JOIN sys.tables tab1
    ON tab1.object_id = fkc.parent_object_id
INNER JOIN sys.schemas sch
    ON tab1.schema_id = sch.schema_id
INNER JOIN sys.columns col1
    ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
INNER JOIN sys.tables tab2
    ON tab2.object_id = fkc.referenced_object_id
INNER JOIN sys.columns col2
    ON col2.column_id = referenced_column_id 
        AND col2.object_id =  tab2.object_id;

1

- สิ่งต่อไปนี้อาจให้สิ่งที่คุณกำลังมองหามากขึ้น:

create Procedure spShowRelationShips 
( 
    @Table varchar(250) = null,
    @RelatedTable varchar(250) = null
)
as
begin
    if @Table is null and @RelatedTable is null
        select  object_name(k.constraint_object_id) ForeginKeyName, 
                object_name(k.Parent_Object_id) TableName, 
                object_name(k.referenced_object_id) RelatedTable, 
                c.Name RelatedColumnName,  
                object_name(rc.object_id) + '.' + rc.name RelatedKeyField
        from sys.foreign_key_columns k
        left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
        left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
        order by 2,3

    if @Table is not null and @RelatedTable is null
        select  object_name(k.constraint_object_id) ForeginKeyName, 
                object_name(k.Parent_Object_id) TableName, 
                object_name(k.referenced_object_id) RelatedTable, 
                c.Name RelatedColumnName,  
                object_name(rc.object_id) + '.' + rc.name RelatedKeyField
        from sys.foreign_key_columns k
        left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
        left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
        where object_name(k.Parent_Object_id) =@Table
        order by 2,3

    if @Table is null and @RelatedTable is not null
        select  object_name(k.constraint_object_id) ForeginKeyName, 
                object_name(k.Parent_Object_id) TableName, 
                object_name(k.referenced_object_id) RelatedTable, 
                c.Name RelatedColumnName,  
                object_name(rc.object_id) + '.' + rc.name RelatedKeyField
        from sys.foreign_key_columns k
        left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
        left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
        where object_name(k.referenced_object_id) =@RelatedTable
        order by 2,3



end

1

นอกจากนี้คุณยังสามารถส่งคืนข้อมูลทั้งหมดเกี่ยวกับForeign Keysโดยปรับคำตอบ @LittleSweetSeas:

SELECT 
   OBJECT_NAME(f.parent_object_id) ConsTable,
   OBJECT_NAME (f.referenced_object_id) refTable,
   COL_NAME(fc.parent_object_id,fc.parent_column_id) ColName
FROM 
   sys.foreign_keys AS f
INNER JOIN 
   sys.foreign_key_columns AS fc 
      ON f.OBJECT_ID = fc.constraint_object_id
INNER JOIN 
   sys.tables t 
      ON t.OBJECT_ID = fc.referenced_object_id
order by
ConsTable

1

ใน SQL Server Management Studio คุณสามารถคลิกขวาที่ตารางใน object explorer แล้วเลือก "View Dependencies" สิ่งนี้จะทำให้คุณเป็นจุดเริ่มต้นที่ดี แสดงตารางมุมมองและขั้นตอนที่อ้างอิงตาราง


0

ลองใช้แบบสอบถามต่อไปนี้

select object_name(sfc.constraint_object_id) AS constraint_name,
       OBJECT_Name(parent_object_id) AS table_name ,
       ac1.name as table_column_name,
       OBJECT_name(referenced_object_id) as reference_table_name,      
       ac2.name as reference_column_name
from  sys.foreign_key_columns sfc
join sys.all_columns ac1 on (ac1.object_id=sfc.parent_object_id and ac1.column_id=sfc.parent_column_id)
join sys.all_columns ac2 on (ac2.object_id=sfc.referenced_object_id and ac2.column_id=sfc.referenced_column_id) 
where sfc.parent_object_id=OBJECT_ID(<main table name>);

สิ่งนี้จะให้ constraint_name, column_names ซึ่งจะอ้างอิงและตารางซึ่งจะขึ้นอยู่กับข้อ จำกัด ที่จะอยู่ที่นั่น


0

คุณสามารถใช้แบบสอบถามนี้เพื่อแสดงForeign keyข้อ จำกัด :

SELECT
K_Table = FK.TABLE_NAME,
FK_Column = CU.COLUMN_NAME,
PK_Table = PK.TABLE_NAME,
PK_Column = PT.COLUMN_NAME,
Constraint_Name = C.CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
INNER JOIN (
SELECT i1.TABLE_NAME, i2.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
) PT ON PT.TABLE_NAME = PK.TABLE_NAME
---- optional:
ORDER BY
1,2,3,4
WHERE PK.TABLE_NAME='YourTable'

นำมาจากhttp://blog.sqlauthority.com/2006/11/01/sql-server-query-to-display-foreign-key-relationships-and-name-of-the-constraint-for-each-table- ในฐานข้อมูล /


0

วิธีที่ง่ายที่สุดในการรับPrimary KeyและForeign Keyโต๊ะคือ:

/*  Get primary key and foreign key for a table */
USE DatabaseName;

SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE CONSTRAINT_NAME LIKE 'PK%' AND
TABLE_NAME = 'TableName'

SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE CONSTRAINT_NAME LIKE 'FK%' AND
TABLE_NAME = 'TableName'

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.