SQL Server에서 외래 키 종속성을 찾는 방법은 무엇입니까?


163

특정 열에서 외래 키 종속성을 모두 찾으려면 어떻게해야합니까?

다른 대안 (SSMS 그래픽, SQL Server 쿼리 / 뷰, 타사 데이터베이스 도구, .NET 코드)은 무엇입니까?

답변:


290

다음 쿼리는 시작하는 데 도움이됩니다. 현재 데이터베이스 내의 모든 외래 키 관계를 나열합니다.

SELECT
    FK_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

데이터베이스 다이어그램 내의 SQL Server Management Studio 내에서 관계를 그래픽으로 볼 수도 있습니다.


8
감사! 특정 열을 가져 오기 위해 << WHERE FK.TABLE_NAME = 'MyTable'및 CU.COLUMN_NAME = 'MyColumn'>>을 추가해야했습니다.
심지어 Mien

1
+1! 그리고 특정 열을 가져와야하지만 모든 테이블에 대해 필요한 경우 "WHERE CU.COLUMN_NAME = 'MyColumn'"이됩니다.
liang

1
Even과 유사-WHERE PK.TABLE_NAME = 'MyTable'을 사용하여 종속 된 테이블을 찾았습니다.
Lanceomagnifico

7
@ samkitshah : 아무도 그렇게 말했다. 질문에는 sql-server라는 태그가 붙어 있으며, 이는 Microsoft 기술입니다. Postgres는 아무 관련이 없습니다.
Neolisk

2
-1 :이 쿼리는 참조 된 테이블에서 기본 키가 아닌 고유 제약 조건 또는 고유 인덱스로 지원되는 외래 키를 누락합니다. 당 MSDN : "A 외래 키 제약 조건은 다른 테이블의 기본 키 제약 조건 만 연결 할 필요가 없습니다; 다른 테이블에서 UNIQUE 제약 조건의 열을 참조하도록 정의 할 수도 있습니다.” 마지막 조인을 제거하여 고유 제한 조건을 사용하고 마지막 두 조인을 제거하여 고유 인덱스를 사용하여 답변을 작성할 수 있지만 리턴되는 정보는 제한됩니다.
더글러스

100

시험: sp_help [table_name]

모든 외래 키를 포함하여 테이블에 대한 모든 정보를 얻습니다.


2
좋은 하나, 매우 유용합니다. 표시된 답변보다 더 기억에 남습니다! 당신은 단지 SMS에서 그들을 볼 수 없다 믿을 수 없어!
JonnyRaa

4
고마워요 그러나 FK를 찾으려면 아래 Michael의 답변 출력을 선호합니다. sp_fkeys [table]
AjV Jsy

.... 또는 그 결과를 얻지 못하면 (그러나 sp_help는 외래 키를 표시합니다) 풀러 버전이 도움이 될 수 있습니다.sp_fkeys @fktable_name='TableName'
AjV Jsy

훌륭한! 간단하고 간결합니다!
제로 결함

39

외래 키 종속성 만 발견하여 테이블 또는 열을 삭제하거나 이름을 바꾸려는 경우 충분하지 않을 수 있습니다.

외래 키와 연결되지 않은 참조 테이블 - 도 검색해야합니다 (외래 키가 정의되지 않았지만 관련 데이터가있는 디자인이 잘못된 데이터베이스가 많이 있음을 확인했습니다) ). 해결책은 모든 테이블에서 열 이름을 검색하고 유사한 열을 찾는 것입니다.

다른 데이터베이스 객체 – 아마도 약간의 주제 일지 모르지만 모든 참조를 찾고 있다면 종속 객체를 확인하는 것이 중요합니다.

GUI 도구 – SSMS“관련 개체 찾기”옵션 또는 ApexSQL 검색 (무료 도구, SSMS에 통합) 과 같은 도구를 사용해 외래 키로 연결된 테이블을 포함한 모든 종속 개체를 식별하십시오.


39

귀하의 질문은 단일 테이블을 대상으로하기 때문에 다음을 사용할 수 있습니다.

EXEC sp_fkeys 'TableName'

나는 그것을 여기에서 찾았다.

https://stackoverflow.com/a/12956348/652519

필요한 정보를 아주 빨리 찾았습니다. 외래 키의 테이블, 열 및 이름이 나열됩니다.

편집하다

다음은 사용할 수있는 다양한 매개 변수를 자세히 설명하는 설명서 링크입니다. https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-fkeys-transact-sql


29

이 스크립트는 덜 비싸다고 생각합니다.

SELECT f.name AS ForeignKey, OBJECT_NAME(f.parent_object_id) AS TableName,
    COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName,
    OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
    COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id

6

제가 정말로 사용하고 싶은 것은 Red Gate Software의 SQL Dependency Tracker입니다 입니다. 테이블, 저장 프로 시저 등과 같은 데이터베이스 개체를 넣을 수 있으며 선택한 항목에 의존하는 다른 모든 개체간에 관계 선을 자동으로 그립니다.

스키마의 종속성을 그래픽으로 잘 보여줍니다.


2
또한 기술이 아닌 사람들에게 데이터베이스 디자인이 리팩토링되기 전에 돈을 써야한다는 것을 보여주는 훌륭한 도구이기도합니다. 그것이 생성하는 그래프는 매우 매력적입니다.
Rob Allen

1
Rob : 전체 데이터베이스 스키마를로드 한 다음 다른 레이아웃간에 변경하는 것을 좋아하므로 모든 것이 날아 다니는 것을 볼 수 있습니다.
TheTXI 2016 년

4

John Sansom에게 대단히 감사합니다. 그의 질문은 훌륭합니다!

또한 : 검색어 끝에 "AND PT.ORDINAL_POSITION = CU.ORDINAL_POSITION"을 추가해야합니다.

기본 키에 여러 필드가있는 경우이 문은 해당 필드를 서로 일치시킵니다 (필자의 경우 쿼리에서 모든 조합을 만들었으므로 기본 키의 두 필드에 대해 해당 외래 키에 대해 4 개의 결과가 있음) .

(죄평 한 점이 충분하지 않아서 John의 답변에 대해서는 언급 할 수 없습니다.)


3

이 쿼리는 테이블의 외래 키에 대한 세부 정보를 반환하며 여러 열 키를 지원합니다.

    SELECT *
    FROM
    (
    SELECT 
    T1.constraint_name ConstraintName,
    T2.COLUMN_NAME ColumnName,
    T3.TABLE_NAME RefTableName, 
    T3.COLUMN_NAME RefColumnName,
    T1.MATCH_OPTION MatchOption, 
    T1.UPDATE_RULE UpdateRule, 
    T1.DELETE_RULE DeleteRule
    FROM 
    INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS T1
    INNER JOIN
    INFORMATION_SCHEMA.KEY_COLUMN_USAGE T2 
    ON T1.CONSTRAINT_NAME = T2.CONSTRAINT_NAME
    INNER JOIN
    INFORMATION_SCHEMA.KEY_COLUMN_USAGE T3 
    ON T1.UNIQUE_CONSTRAINT_NAME = T3.CONSTRAINT_NAME 
    AND T2.ORDINAL_POSITION = T3.ORDINAL_POSITION) A
    WHERE A.ConstraintName = 'table_name'

2

긴 검색 후 작동하는 솔루션을 찾았습니다. 내 데이터베이스는 sys.foreign_key_columns를 사용하지 않으며 information_schema.key_column_usage에는 기본 키만 포함되어 있습니다.

SQL Server 2015를 사용합니다

솔루션 1 (드물게 사용됨)

다른 솔루션이 작동하지 않으면 정상적으로 작동합니다.

        WITH CTE AS
        (
            SELECT 
                TAB.schema_id,
                TAB.name,
                COL.name AS COLNAME,
                COl.is_identity
            FROM 
                sys.tables TAB INNER JOIN sys.columns COL 
                    ON TAB.object_id = COL.object_id
        )
        SELECT 
            DB_NAME() AS [Database], 
            SCHEMA_NAME(Child.schema_id) AS 'Schema',
            Child.name AS 'ChildTable',
            Child.COLNAME AS 'ChildColumn',
            Parent.name AS 'ParentTable',
            Parent.COLNAME AS 'ParentColumn'
        FROM 
            cte Child INNER JOIN CTE Parent
                ON 
                    Child.COLNAME=Parent.COLNAME AND 
                    Child.name<>Parent.name AND 
                    Child.is_identity+1=Parent.is_identity

솔루션 2 (일반적으로 사용)

대부분의 경우 이것은 잘 작동합니다.

        SELECT
            DB_NAME() AS [Database], 
            SCHEMA_NAME(fk.schema_id) AS 'Schema',
            fk.name 'Name',
            tp.name 'ParentTable',
            cp.name 'ParentColumn',
            cp.column_id,
            tr.name 'ChildTable',
            cr.name 'ChildColumn',
            cr.column_id
        FROM
            sys.foreign_keys fk
        INNER JOIN
            sys.tables tp ON fk.parent_object_id = tp.object_id
        INNER JOIN
            sys.tables tr ON fk.referenced_object_id = tr.object_id
        INNER JOIN
            sys.foreign_key_columns fkc ON fkc.constraint_object_id = fk.object_id
        INNER JOIN
            sys.columns cp ON fkc.parent_column_id = cp.column_id AND fkc.parent_object_id = cp.object_id
        INNER JOIN
            sys.columns cr ON fkc.referenced_column_id = cr.column_id AND fkc.referenced_object_id = cr.object_id
        WHERE 
            -- CONCAT(SCHEMA_NAME(fk.schema_id), '.', tp.name, '.', cp.name) LIKE '%my_table_name%' OR
            -- CONCAT(SCHEMA_NAME(fk.schema_id), '.', tr.name, '.', cr.name) LIKE '%my_table_name%' 
        ORDER BY
            tp.name, cp.column_id

2

INFORMATION_SCHEMA.KEY_COLUMN_USAGE 및 sys.foreign_key_columns를 사용하여 테이블의 외래 키 메타 데이터 (예 : 제약 조건 이름, 참조 테이블 및 참조 열)를 가져올 수 있습니다.

아래는 쿼리입니다.

SELECT  CONSTRAINT_NAME, COLUMN_NAME, ParentTableName, RefTableName,RefColName FROM 
    (SELECT CONSTRAINT_NAME,COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = '<tableName>') constraint_details
    INNER JOIN  
    (SELECT ParentTableName, RefTableName,name ,COL_NAME(fc.referenced_object_id,fc.referenced_column_id) RefColName  FROM (SELECT object_name(parent_object_id) ParentTableName,object_name(referenced_object_id) RefTableName,name,OBJECT_ID  FROM sys.foreign_keys WHERE parent_object_id = object_id('<tableName>') ) f 
    INNER JOIN   
    sys.foreign_key_columns AS fc  ON  f.OBJECT_ID = fc.constraint_object_id ) foreign_key_detail 
    on foreign_key_detail.name = constraint_details.CONSTRAINT_NAME

1

@ "John Sansom"답변에 대한 메모

외래 키 의존성을 찾고 있다면 PT Where 절이 다음과 같아야한다고 생각합니다.

i1.CONSTRAINT_TYPE = 'FOREIGN KEY'  -- instead of 'PRIMARY KEY'

그리고 그것 ON 조건 :

ON PT.TABLE_NAME = FK.TABLE_NAME  instead of PK.TABLE_NAME

일반적으로 외래 테이블의 기본 키가 사용 되므로이 문제는 이전에 발견되지 않았다고 생각합니다.


0
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

그것은 당신에게 줄 것이다 :

FK가 속한 FK 자체 스키마

  • "참조 테이블"또는 FK가있는 테이블
  • "참조 열"또는 FK를 가리키는 참조 테이블 내부의 열
  • "참조 테이블"또는 FK가 가리키는 키 열이있는 테이블
  • "참조 열"또는 FK가 가리키는 키인 열

-1

USE information_schema;

SELECT COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
FROM KEY_COLUMN_USAGE
WHERE (table_name = *tablename*) AND NOT (REFERENCED_TABLE_NAME IS NULL)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.