SQL Server에서 주어진 테이블을 참조하는 모든 외래 키를 어떻게 나열합니까?


736

SQL Server 데이터베이스에서 참조가 높은 테이블을 제거해야합니다. 테이블을 삭제하기 위해 제거해야 할 모든 외래 키 제약 조건의 목록을 어떻게 얻을 수 있습니까?

(관리 스튜디오의 GUI에서 클릭하는 것보다 SQL이 선호합니다.)


도움 이 필요하면 테이블의 모든 외래 키를 스크립팅하는 방법을 참조하십시오 . 업데이트 : 링크를 더 이상 사용할 수 없지만 관련 질문에 대한 답변 으로 관련 SQL이 복사되었습니다 . GUI를 통해 종속성을 볼 수도 있습니다.
Galwegian

답변:


1126

왜 아무도 제안하지 않았지만 sp_fkeys주어진 테이블에 대한 외래 키를 쿼리 하는 데 사용 합니다.

EXEC sp_fkeys 'TableName'

스키마를 지정할 수도 있습니다.

EXEC sp_fkeys @pktable_name = 'TableName', @pktable_owner = 'dbo'

스키마를 지정하지 않으면 문서 는 다음을 나타냅니다.

pktable_owner를 지정하지 않으면 기본 DBMS의 기본 테이블 가시성 규칙이 적용됩니다.

SQL Server에서 현재 사용자가 지정된 이름의 테이블을 소유 한 경우 해당 테이블의 열이 반환됩니다. pktable_owner를 지정하지 않고 현재 사용자가 지정된 pktable_name을 가진 테이블을 소유하지 않으면 프로시 저는 데이터베이스 소유자가 소유 한 지정된 pktable_name을 가진 테이블을 찾습니다. 존재하는 경우 해당 테이블의 열이 반환됩니다.


41
어떤 이유로 SQL 2008 데이터베이스에서 작동하지 않습니다. sp_help는 관계를 보여 주지만이 명령은 그렇지 않습니다.
tbone

21
@ tbone : 매개 변수를 완전히 지정하지 않는 것과 같은 문제가 발생했습니다. 데이터베이스 D에서 O가 소유 한 테이블 T가 주어지면 EXEC sp_fkeys \ @ pktable_name = 'T', \ @ pktable_owner = 'O', \ @ pktable_qualifier = 'D'를 실행해야합니다. EXEC sp_tables의 출력을 살펴보십시오 \ @ table_name = 'T'는 매개 변수 값이 무엇인지 알아냅니다.
Mads Ravn

3
@JustinRusso 테이블을 생성하여 결과를 해결하고 결과를 테이블에 저장 한 다음 특정 열을 선택할 수 있습니다. 예를 들어이 링크 를 확인하십시오 :).
John Odom

3
SSMS 2014에서 잘 작동합니다. 감사합니다.
.

7
그것은 이미 위의 의견에서 대답되었습니다 : 명확성을 위해-EXEC sp_fkeys @pktable_name = N'Department ', @ pktable_owner = N'dbo'; msdn.microsoft.com/en-NZ/library/ms175090.aspx
Tejas Patel

233

SQL Server Management Studio에서 데이터베이스 다이어그램 기능을 사용하지만 SQL Server 2008 (2005는 없음)에서 제외되었습니다.

참조 테이블 및 열 이름 목록을 얻으려면 ...

select 
    t.name as TableWithForeignKey, 
    fk.constraint_column_id as FK_PartNo, c.
    name as ForeignKeyColumn 
from 
    sys.foreign_key_columns as fk
inner join 
    sys.tables as t on fk.parent_object_id = t.object_id
inner join 
    sys.columns as c on fk.parent_object_id = c.object_id and fk.parent_column_id = c.column_id
where 
    fk.referenced_object_id = (select object_id 
                               from sys.tables 
                               where name = 'TableOthersForeignKeyInto')
order by 
    TableWithForeignKey, FK_PartNo

외래 키 제약 조건의 이름을 가져 오려면

select distinct name from sys.objects where object_id in 
(   select fk.constraint_object_id from sys.foreign_key_columns as fk
    where fk.referenced_object_id = 
        (select object_id from sys.tables where name = 'TableOthersForeignKeyInto')
)

4
부모 대신 reference_object_id를 사용했지만 훌륭합니다. object_id가있는 sys.objects에서 다른 이름을 선택하십시오. (fk.referenced_object_id = (sys = table. '인 sys.tables에서 object_id를 선택하십시오.))
chillitom

4
첫 번째 쿼리의 선택에 "object_name (constraint_object_id)"를 추가하여 FK의 이름을 얻을 수 있습니다.
sam yi

3
당신은 객체 ID를 얻을 수 있습니다 object_id ( 'TableOthersForeignKeyInto')
IvanH

189

이것은 당신에게 제공합니다 :

  • FK 자체
  • FK가 속한 스키마
  • " 참조 테이블 "또는 FK가있는 테이블
  • " 참조 열 "또는 FK를 가리키는 참조 테이블 내부의 열
  • " 참조 테이블 "또는 FK가 가리키는 키 열이있는 테이블
  • " 참조 된 열 "또는 FK가 가리키는 키인 열

아래 코드 :

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

13
나중에 결과를 필터링하려는 경우 이것이 내 의견에 가장 적합한 답변입니다.
Faliorn

잘 작동합니다! a) 모든 열 이름 앞에 "Fk"/ "Key"를 접두사로 추가하고 b) 모든 열 이름에 "Name"으로 접미사를 붙입니다. c) 밑줄을 제거합니다. d) KeyTableSchemaName 추가, e) 기본값 추가 order by: KeyTableSchemaName, KeyTableName, KeyColumnName, FkTableSchemaName, FkTableName, FkName 및 f) 열 순서 변경 : KeyTableSchemaName, KeyTableName, KeyColumnName, FkTableSchemaName, FkTableName, FkName, FkColumnName, a / b / c / d 명명 규칙 가장 가능성있는 사용법에 대한 규칙 및 d / e (a의 FK 종속 항목 나열 Table).
Tom

그런 훌륭한 답변과 유용한 쿼리. 감사합니다
Rich Dominelli

153

이 시도 :

sp_help 'TableName'

2
DB를 수동으로 탐색하고 있는지 확인하는 멋진 도우미 방법입니다. 또한 Azure SQL Server에서도 작동합니다.
Pac0

48

다른 객체에 대한 참조도 염두에 두어야합니다.

테이블이 다른 테이블에 의해 고도로 참조 된 경우, 뷰, 스토어드 프로 시저, 함수 등과 같은 다른 오브젝트에 의해 참조 될 수도 있습니다.

SSMS의 '종속성보기'대화 상자와 같은 GUI 도구 또는 ApexSQL 검색 과 같은 무료 도구를 사용하는 것이 좋습니다 . 다른 객체에서 종속성을 검색하면 SQL로만 수행하려는 경우 오류가 발생하기 쉽습니다.

SQL이 유일한 옵션이라면 다음과 같이 시도해 볼 수 있습니다.

select O.name as [Object_Name], C.text as [Object_Definition]
from sys.syscomments C
inner join sys.all_objects O ON C.id = O.object_id
where C.text like '%table_name%'

21

원래 질문은 테이블을 제거 할 수 있도록 모든 외래 키 목록을 참조가 높은 테이블로 가져 오도록 요청했습니다.

이 작은 쿼리는 모든 외래 키를 특정 테이블에 삭제하는 데 필요한 모든 '외래 키 삭제'명령을 반환합니다.

SELECT 
   'ALTER TABLE ['+sch.name+'].['+referencingTable.Name+'] DROP CONSTRAINT ['+foreignKey.name+']' '[DropCommand]'
FROM sys.foreign_key_columns fk
    JOIN sys.tables referencingTable ON fk.parent_object_id = referencingTable.object_id
    JOIN sys.schemas sch ON referencingTable.schema_id = sch.schema_id
    JOIN sys.objects foreignKey ON foreignKey.object_id = fk.constraint_object_id
    JOIN sys.tables referencedTable ON fk.referenced_object_id = referencedTable.object_id
WHERE referencedTable.name = 'MyTableName'

출력 예 :

[DropCommand]
ALTER TABLE [dbo].[OtherTable1] DROP CONSTRAINT [FK_OtherTable1_MyTable]
ALTER TABLE [dbo].[OtherTable2] DROP CONSTRAINT [FK_OtherTable2_MyTable]

WHERE-clause를 생략하여 현재 데이터베이스의 모든 외래 키에 대한 삭제 명령을 가져 오십시오.


17

내가 사용할 SQL 코드는 다음과 같습니다.

SELECT 
   f.name AS 'Name of Foreign Key',
   OBJECT_NAME(f.parent_object_id) AS 'Table name',
   COL_NAME(fc.parent_object_id,fc.parent_column_id) AS 'Fieldname',
   OBJECT_NAME(t.object_id) AS 'References Table name',
   COL_NAME(t.object_id,fc.referenced_column_id) AS 'References fieldname',

   'ALTER TABLE [' + OBJECT_NAME(f.parent_object_id) + ']  DROP CONSTRAINT [' + f.name + ']' AS 'Delete foreign key',

   'ALTER TABLE [' + OBJECT_NAME(f.parent_object_id) + ']  WITH NOCHECK ADD CONSTRAINT [' + 
        f.name + '] FOREIGN KEY([' + COL_NAME(fc.parent_object_id,fc.parent_column_id) + ']) REFERENCES ' + 
        '[' + OBJECT_NAME(t.object_id) + '] ([' +
        COL_NAME(t.object_id,fc.referenced_column_id) + '])' AS 'Create foreign key'
    -- , delete_referential_action_desc AS 'UsesCascadeDelete'
FROM sys.foreign_keys AS f,
     sys.foreign_key_columns AS fc,
     sys.tables t 
WHERE f.OBJECT_ID = fc.constraint_object_id
AND t.OBJECT_ID = fc.referenced_object_id
AND OBJECT_NAME(t.object_id) = 'Employees'      --  Just show the FKs which reference a particular table
ORDER BY 2

특히 명확한 SQL은 아니므로 예제를 살펴 보겠습니다.

따라서 EmployeesMicrosoft의 사랑받는 Northwind데이터베이스에 테이블 을 삭제하려고한다고 가정 했지만 SQL Server는 하나 이상의 외래 키로 인해이 작업을 수행하지 못하게한다고 말했습니다.

위의 SQL 명령은 이러한 결과를 반환합니다 ...

외래 키

Employees테이블 을 참조하는 3 개의 외래 키가 있음을 보여줍니다 . 즉,이 세 개의 외래 키가 처음 삭제 될 때까지이 테이블을 삭제 (삭제) 할 수 없습니다.

결과에서 첫 번째 행은 다음 외래 키 제약 조건이 결과에 표시되는 방식입니다.

ALTER TABLE [dbo].[Employees]  WITH NOCHECK 
ADD CONSTRAINT [FK_Employees_Employees] FOREIGN KEY([ReportsTo])
REFERENCES [dbo].[Employees] ([EmployeeID])

두 번째부터 마지막 ​​열은 이러한 외래 키 중 하나 를 삭제하는 데 사용해야하는 SQL 명령을 보여줍니다 .

ALTER TABLE [Employees] DROP CONSTRAINT [FK_Employees_Employees]

... 오른쪽 열에는이를 생성 하는 SQL이 표시 됩니다.

ALTER TABLE [Employees] WITH NOCHECK 
ADD CONSTRAINT [FK_Employees_Employees] 
FOREIGN KEY([ReportsTo]) REFERENCES [Employees] ([EmployeeID])

이러한 모든 명령을 사용하면 테이블을 삭제 한 다음 나중에 다시 만들 수 있도록 관련 외래 키를 삭제하는 데 필요한 모든 것이 있습니다.

휴 도움이 되었기를 바랍니다.


교차 조인 대신 내부 조인과 on 절을 사용하면 더 명확 해집니다. 그러나 이것은 도움이되었습니다!
TamusJRoyce

16
SELECT PKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
       PKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O1.SCHEMA_ID)),
       PKTABLE_NAME = CONVERT(SYSNAME,O1.NAME),
       PKCOLUMN_NAME = CONVERT(SYSNAME,C1.NAME),
       FKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
       FKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O2.SCHEMA_ID)),
       FKTABLE_NAME = CONVERT(SYSNAME,O2.NAME),
       FKCOLUMN_NAME = CONVERT(SYSNAME,C2.NAME),
       -- Force the column to be non-nullable (see SQL BU 325751)
       --KEY_SEQ             = isnull(convert(smallint,k.constraint_column_id), sysconv(smallint,0)),
       UPDATE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsUpdateCascade') 
                                        WHEN 1 THEN 0
                                        ELSE 1
                                      END),
       DELETE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsDeleteCascade') 
                                        WHEN 1 THEN 0
                                        ELSE 1
                                      END),
       FK_NAME = CONVERT(SYSNAME,OBJECT_NAME(F.OBJECT_ID)),
       PK_NAME = CONVERT(SYSNAME,I.NAME),
       DEFERRABILITY = CONVERT(SMALLINT,7)   -- SQL_NOT_DEFERRABLE
FROM   SYS.ALL_OBJECTS O1,
       SYS.ALL_OBJECTS O2,
       SYS.ALL_COLUMNS C1,
       SYS.ALL_COLUMNS C2,
       SYS.FOREIGN_KEYS F
       INNER JOIN SYS.FOREIGN_KEY_COLUMNS K
         ON (K.CONSTRAINT_OBJECT_ID = F.OBJECT_ID)
       INNER JOIN SYS.INDEXES I
         ON (F.REFERENCED_OBJECT_ID = I.OBJECT_ID
             AND F.KEY_INDEX_ID = I.INDEX_ID)
WHERE  O1.OBJECT_ID = F.REFERENCED_OBJECT_ID
       AND O2.OBJECT_ID = F.PARENT_OBJECT_ID
       AND C1.OBJECT_ID = F.REFERENCED_OBJECT_ID
       AND C2.OBJECT_ID = F.PARENT_OBJECT_ID
       AND C1.COLUMN_ID = K.REFERENCED_COLUMN_ID
       AND C2.COLUMN_ID = K.PARENT_COLUMN_ID

15

가장 간단한 방법은 SQL에서 sys.foreign_keys_columns를 사용하는 것입니다. 여기에 테이블에는 참조 열 및 테이블뿐만 아니라 참조 열 ID 참조 테이블 ID가있는 모든 외래 키의 개체 ID가 포함됩니다. Id가 일정하게 유지되면 결과는 스키마뿐만 아니라 테이블의 추가 수정에도 신뢰할 수 있습니다.

질문:

SELECT    
OBJECT_NAME(fkeys.constraint_object_id) foreign_key_name
,OBJECT_NAME(fkeys.parent_object_id) referencing_table_name
,COL_NAME(fkeys.parent_object_id, fkeys.parent_column_id) referencing_column_name
,OBJECT_SCHEMA_NAME(fkeys.parent_object_id) referencing_schema_name
,OBJECT_NAME (fkeys.referenced_object_id) referenced_table_name
,COL_NAME(fkeys.referenced_object_id, fkeys.referenced_column_id) 
referenced_column_name
,OBJECT_SCHEMA_NAME(fkeys.referenced_object_id) referenced_schema_name
FROM sys.foreign_key_columns AS fkeys

'where'를 사용하여 필터를 추가 할 수도 있습니다.

WHERE OBJECT_NAME(fkeys.parent_object_id) = 'table_name' AND 
OBJECT_SCHEMA_NAME(fkeys.parent_object_id) = 'schema_name'

이는 전체 DB 구문 / 참조 테이블 세트를 제거해야 할 때 유용합니다.
Morvael

12
SELECT
  object_name(parent_object_id),
  object_name(referenced_object_id),
  name 
FROM sys.foreign_keys
WHERE parent_object_id = object_id('Table Name')

11

이 스크립트를 사용하여 외래 키와 관련된 모든 세부 정보를 찾습니다. 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

8

먼저

EXEC sp_fkeys 'Table', 'Schema'

그런 다음 NimbleText 를 사용 하여 결과를 재생하십시오.


5

위의 좋은 답변. 그러나 나는 하나의 쿼리로 대답하는 것을 선호 합니다. 이 코드는 sys.sp_helpconstraint (sys proc)에서 가져 왔습니다.

이것이 tbl과 관련된 외래 키가있는 경우 Microsoft가 찾는 방식입니다.

--setup variables. Just change 'Customer' to tbl you want
declare @objid int,
    @objname nvarchar(776)
select @objname = 'Customer'    
select @objid = object_id(@objname)

if exists (select * from sys.foreign_keys where referenced_object_id = @objid)
    select 'Table is referenced by foreign key' =
        db_name() + '.'
        + rtrim(schema_name(ObjectProperty(parent_object_id,'schemaid')))
        + '.' + object_name(parent_object_id)
        + ': ' + object_name(object_id)
    from sys.foreign_keys 
    where referenced_object_id = @objid 
    order by 1

대답은 다음과 같습니다. test_db_name.dbo.Account : FK_Account_Customer


3
이것은 실제로 4 개의 개별 쿼리 문과 같습니다. 이것은 하나의 문에서 효과적으로 동일한 작업을 수행합니다. select db_name() + '.' + schema_name(ObjectProperty(parent_object_id,'schemaid')) + '.' + object_name(parent_object_id) + ': ' + object_name(object_id) AS "FK Reference" from sys.foreign_keys where referenced_object_id = object_id('Customer')
hajikelist

5
SELECT
OBJECT_NAME(parent_object_id) 'Parent table',
c.NAME 'Parent column name',
OBJECT_NAME(referenced_object_id) 'Referenced table',
cref.NAME 'Referenced column name'
FROM 
sys.foreign_key_columns fkc 
INNER JOIN 
sys.columns c 
   ON fkc.parent_column_id = c.column_id 
      AND fkc.parent_object_id = c.object_id
INNER JOIN 
sys.columns cref 
   ON fkc.referenced_column_id = cref.column_id 
      AND fkc.referenced_object_id = cref.object_id  where   OBJECT_NAME(parent_object_id) = 'tablename'

모든 테이블의 외래 키 관계를 얻으려면 where절을 제외하고 대신 테이블 이름을 작성하십시오tablename


4
 SELECT OBJECT_NAME(fk.parent_object_id) as ReferencingTable, 
        OBJECT_NAME(fk.constraint_object_id) as [FKContraint]
  FROM sys.foreign_key_columns as fk
 WHERE fk.referenced_object_id = OBJECT_ID('ReferencedTable', 'U')

외래 키 제약 조건 인 경우에만 관계가 표시됩니다. 내 데이터베이스는 분명히 FK 제약 조건보다 오래된 것입니다. 일부 테이블은 트리거를 사용하여 참조 무결성을 강화하고 때로는 관계를 나타내는 비슷한 이름의 열이 있습니다 (그리고 참조 무결성이 전혀 없음).

다행히도 일관된 이름 지정 장면이 있으므로 다음과 같은 참조 테이블과 뷰를 찾을 수 있습니다.

SELECT OBJECT_NAME(object_id) from sys.columns where name like 'client_id'

이 선택을 관련 테이블에서 수행해야하는 스크립트를 생성하는 기초로 사용했습니다.


3

@Gishu가 수행 한 작업으로 SQL Server 2005에서 다음 SQL을 생성하고 사용할 수있었습니다.

SELECT t.name AS TableWithForeignKey, fk.constraint_column_id AS FK_PartNo, 
       c.name AS ForeignKeyColumn, o.name AS FK_Name 
  FROM sys.foreign_key_columns AS fk
       INNER JOIN sys.tables AS t ON fk.parent_object_id = t.object_id
       INNER JOIN sys.columns AS c ON fk.parent_object_id = c.object_id 
                                  AND fk.parent_column_id = c.column_id
       INNER JOIN sys.objects AS o ON fk.constraint_object_id = o.object_id
  WHERE fk.referenced_object_id = (SELECT object_id FROM sys.tables 
                                        WHERE name = 'TableOthersForeignKeyInto')
  ORDER BY TableWithForeignKey, FK_PartNo;

어느 하나의 쿼리에서 테이블, 열 및 외래 키 이름을 모두 표시합니다.


3

데이터베이스의 모든 테이블에 대한 기본 키 및 고유 키 결정 ...

여기에는 모든 제약 조건이 나열되고 결국에는 필터를 넣을 수 있습니다

/* 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 를 참조하십시오.


2
질문에 대한 정보가 너무 많습니다. 질문에 대답하기 위해 설명을 추가하고 여분의 코드를 제거 할 수 있습니까? 당신은 두 개의 서로 다른 질문이 정확한 대답을 게시하고, 각각은 필요 부분 이 답변을.
Andrew Barber

2
답변을 편집했습니다-데이터베이스의 모든 테이블에 대한 기본 키와 고유 키를 결정하십시오 ... 질문은 모든 참조에 대한 것이므로 여기에 답이 적절하다고 생각합니다.
dekdev

3

나는 2008 년부터 이것을 사용하고 있습니다. 나열된 다른 솔루션과 비슷하지만 필드 이름은 대소 문자 구분 (LatBin) 데이터 정렬을 처리하기에 적합한 경우입니다. 또한 단일 테이블 이름을 제공하고 해당 테이블의 정보 만 검색 할 수 있습니다.

-->>SPECIFY THE DESIRED DB
USE ???
GO

/*********************************************************************************************

    LIST OUT ALL PRIMARY AND FOREIGN KEY CONSTRAINTS IN A DB OR FOR A SPECIFIED TABLE

*********************************************************************************************/
DECLARE @tblName VARCHAR(255) 

/*******************/

    SET @tblName = NULL-->NULL will return all PK/FK constraints for every table in the database

/*******************/

SELECT PKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()), 
       PKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O1.schema_id)), 
       PKTABLE_NAME = CONVERT(SYSNAME,O1.name), 
       PKCOLUMN_NAME = CONVERT(SYSNAME,C1.name), 
       FKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()), 
       FKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O2.schema_id)), 
       FKTABLE_NAME = CONVERT(SYSNAME,O2.name), 
       FKCOLUMN_NAME = CONVERT(SYSNAME,C2.name), 
       -- Force the column to be non-nullable (see SQL BU 325751) 
       KEY_SEQ             = isnull(convert(smallint,K.constraint_column_id),0), 
       UPDATE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.object_id,'CnstIsUpdateCascade')  
                                        WHEN 1 THEN 0 
                                        ELSE 1 
                                      END), 
       DELETE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.object_id,'CnstIsDeleteCascade')  
                                        WHEN 1 THEN 0 
                                        ELSE 1 
                                      END), 
       FK_NAME = CONVERT(SYSNAME,OBJECT_NAME(F.object_id)), 
       PK_NAME = CONVERT(SYSNAME,I.name), 
       DEFERRABILITY = CONVERT(SMALLINT,7)   -- SQL_NOT_DEFERRABLE 
FROM   sys.all_objects O1, 
       sys.all_objects O2, 
       sys.all_columns C1, 
       sys.all_columns C2, 
       sys.foreign_keys F 
       INNER JOIN sys.foreign_key_columns K 
         ON (K.constraint_object_id = F.object_id) 
       INNER JOIN sys.indexes I 
         ON (F.referenced_object_id = I.object_id 
             AND F.key_index_id = I.index_id) 
WHERE  O1.object_id = F.referenced_object_id 
       AND O2.object_id = F.parent_object_id 
       AND C1.object_id = F.referenced_object_id 
       AND C2.object_id = F.parent_object_id 
       AND C1.column_id = K.referenced_column_id
       AND C2.column_id = K.parent_column_id
       AND (   O1.name = @tblName 
            OR O2.name = @tblName
            OR @tblName IS null)
ORDER BY PKTABLE_NAME,FKTABLE_NAME

2

선택한 ID에 대한 모든 책임을 계산하는 방법이 있습니다. @dbTableName 값, @dbRowId 값 및 해당 유형을 변경하십시오 (int 인 경우 82 행에서 ''를 제거해야하는 경우 (..SET @SQL = ..)). 즐겨.

DECLARE @dbTableName varchar(max) = 'User'
DECLARE @dbRowId uniqueidentifier = '21d34ecd-c1fd-11e2-8545-002219a42e1c'

DECLARE @FK_ROWCOUNT int
DECLARE @SQL nvarchar(max)

DECLARE @PKTABLE_QUALIFIER sysname
DECLARE @PKTABLE_OWNER sysname
DECLARE @PKTABLE_NAME sysname
DECLARE @PKCOLUMN_NAME sysname
DECLARE @FKTABLE_QUALIFIER sysname
DECLARE @FKTABLE_OWNER sysname
DECLARE @FKTABLE_NAME sysname
DECLARE @FKCOLUMN_NAME sysname
DECLARE @UPDATE_RULE smallint
DECLARE @DELETE_RULE smallint
DECLARE @FK_NAME sysname
DECLARE @PK_NAME sysname
DECLARE @DEFERRABILITY sysname

IF OBJECT_ID('tempdb..#Temp1') IS NOT NULL
    DROP TABLE #Temp1;
CREATE TABLE #Temp1 ( 
    PKTABLE_QUALIFIER sysname,
    PKTABLE_OWNER sysname,
    PKTABLE_NAME sysname,
    PKCOLUMN_NAME sysname,
    FKTABLE_QUALIFIER sysname,
    FKTABLE_OWNER sysname,
    FKTABLE_NAME sysname,
    FKCOLUMN_NAME sysname,
    UPDATE_RULE smallint,
    DELETE_RULE smallint,
    FK_NAME sysname,
    PK_NAME sysname,
    DEFERRABILITY sysname,
    FK_ROWCOUNT int
    );
DECLARE FK_Counter_Cursor CURSOR FOR
    SELECT PKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
       PKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O1.SCHEMA_ID)),
       PKTABLE_NAME = CONVERT(SYSNAME,O1.NAME),
       PKCOLUMN_NAME = CONVERT(SYSNAME,C1.NAME),
       FKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
       FKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O2.SCHEMA_ID)),
       FKTABLE_NAME = CONVERT(SYSNAME,O2.NAME),
       FKCOLUMN_NAME = CONVERT(SYSNAME,C2.NAME),
       -- Force the column to be non-nullable (see SQL BU 325751)
       --KEY_SEQ             = isnull(convert(smallint,k.constraint_column_id), sysconv(smallint,0)),
       UPDATE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsUpdateCascade') 
                                        WHEN 1 THEN 0
                                        ELSE 1
                                      END),
       DELETE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsDeleteCascade') 
                                        WHEN 1 THEN 0
                                        ELSE 1
                                      END),
       FK_NAME = CONVERT(SYSNAME,OBJECT_NAME(F.OBJECT_ID)),
       PK_NAME = CONVERT(SYSNAME,I.NAME),
       DEFERRABILITY = CONVERT(SMALLINT,7)   -- SQL_NOT_DEFERRABLE
    FROM   SYS.ALL_OBJECTS O1,
           SYS.ALL_OBJECTS O2,
           SYS.ALL_COLUMNS C1,
           SYS.ALL_COLUMNS C2,
           SYS.FOREIGN_KEYS F
           INNER JOIN SYS.FOREIGN_KEY_COLUMNS K
             ON (K.CONSTRAINT_OBJECT_ID = F.OBJECT_ID)
           INNER JOIN SYS.INDEXES I
             ON (F.REFERENCED_OBJECT_ID = I.OBJECT_ID
                 AND F.KEY_INDEX_ID = I.INDEX_ID)
    WHERE  O1.OBJECT_ID = F.REFERENCED_OBJECT_ID
           AND O2.OBJECT_ID = F.PARENT_OBJECT_ID
           AND C1.OBJECT_ID = F.REFERENCED_OBJECT_ID
           AND C2.OBJECT_ID = F.PARENT_OBJECT_ID
           AND C1.COLUMN_ID = K.REFERENCED_COLUMN_ID
           AND C2.COLUMN_ID = K.PARENT_COLUMN_ID
           AND O1.NAME = @dbTableName
OPEN FK_Counter_Cursor;
FETCH NEXT FROM FK_Counter_Cursor INTO @PKTABLE_QUALIFIER, @PKTABLE_OWNER, @PKTABLE_NAME, @PKCOLUMN_NAME, @FKTABLE_QUALIFIER, @FKTABLE_OWNER, @FKTABLE_NAME, @FKCOLUMN_NAME, @UPDATE_RULE, @DELETE_RULE, @FK_NAME, @PK_NAME, @DEFERRABILITY;
WHILE @@FETCH_STATUS = 0
   BEGIN
        SET @SQL = 'SELECT @dbCountOut = COUNT(*) FROM [' + @FKTABLE_NAME + '] WHERE [' + @FKCOLUMN_NAME + '] = ''' + CAST(@dbRowId AS varchar(max)) + '''';
        EXECUTE sp_executesql @SQL, N'@dbCountOut int OUTPUT', @dbCountOut = @FK_ROWCOUNT OUTPUT;
        INSERT INTO #Temp1 (PKTABLE_QUALIFIER, PKTABLE_OWNER, PKTABLE_NAME, PKCOLUMN_NAME, FKTABLE_QUALIFIER, FKTABLE_OWNER, FKTABLE_NAME, FKCOLUMN_NAME, UPDATE_RULE, DELETE_RULE, FK_NAME, PK_NAME, DEFERRABILITY, FK_ROWCOUNT) VALUES (@FKTABLE_QUALIFIER, @PKTABLE_OWNER, @PKTABLE_NAME, @PKCOLUMN_NAME, @FKTABLE_QUALIFIER, @FKTABLE_OWNER, @FKTABLE_NAME, @FKCOLUMN_NAME, @UPDATE_RULE, @DELETE_RULE, @FK_NAME, @PK_NAME, @DEFERRABILITY, @FK_ROWCOUNT)
      FETCH NEXT FROM FK_Counter_Cursor INTO @PKTABLE_QUALIFIER, @PKTABLE_OWNER, @PKTABLE_NAME, @PKCOLUMN_NAME, @FKTABLE_QUALIFIER, @FKTABLE_OWNER, @FKTABLE_NAME, @FKCOLUMN_NAME, @UPDATE_RULE, @DELETE_RULE, @FK_NAME, @PK_NAME, @DEFERRABILITY;
   END;
CLOSE FK_Counter_Cursor;
DEALLOCATE FK_Counter_Cursor;
GO
SELECT * FROM #Temp1
GO

2

MySQL 서버에는 information_schema.REFERENTIAL_CONSTRAINTS테이블 FYI 가 있으며 테이블 이름 또는 참조 테이블 이름으로 필터링 할 수 있습니다.


2

SQL Server에서 주어진 테이블을 참조하는 모든 외래 키 목록 :

다음 쿼리를 통해 참조 테이블 이름과 열 이름을 얻을 수 있습니다 ...

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) = 'TableName'

그리고 당신의 이해를 위해 다음 스크린 샷 ...

여기에 이미지 설명을 입력하십시오


1

선택한 테이블과 관련된 외래 키를 가져옵니다. * _FIRSTABLENAME_SECONDTABLENAME 형식을 가정합니다.

 declare @tablename as varchar(MAX)
 SET @tablename = 'yourtablename'
 SELECT name
 FROM YOURDATABASE.sys.objects
 WHERE type_desc = 'FOREIGN_KEY_CONSTRAINT' and (name LIKE '%_' + @tablename + 'empdb_%' or name LIKE '%_' + @tablename )

이것은 더 일반적인 형태입니다.

 SELECT name
 FROM YOURDATABASE_PROD.sys.objects
 WHERE type_desc = 'FOREIGN_KEY_CONSTRAINT' and name LIKE '%' + @tablename + '%' and
 name NOT LIKE '[a-zA-Z0-9]' + @tablename + '%' and name NOT LIKE '%' + @tablename + '[a-zA-Z0-9]' 

1

다음 솔루션이 저에게 효과적입니다.

--Eliminar las llaves foraneas
declare @query varchar(8000)
declare cursorRecorrerTabla cursor for

SELECT  'ALTER TABLE [PoaComFinH].['+sch.name+'].['+referencingTable.Name+'] DROP CONSTRAINT ['+foreignKey.name+']' 'query'
FROM PoaComFinH.sys.foreign_key_columns fk
JOIN PoaComFinH.sys.tables referencingTable ON fk.parent_object_id = referencingTable.object_id
JOIN PoaComFinH.sys.schemas sch ON referencingTable.schema_id = sch.schema_id
JOIN PoaComFinH.sys.objects foreignKey ON foreignKey.object_id = fk.constraint_object_id
JOIN PoaComFinH.sys.tables referencedTable ON fk.referenced_object_id = referencedTable.object_id


--3ro. abrir el cursor.
open cursorRecorrerTabla
fetch next from cursorRecorrerTabla
into @query
while @@fetch_status = 0
begin
--inicio cuerpo del cursor
    print @query
    exec(@query)
--fin cuerpo del cursor
fetch next from cursorRecorrerTabla
into @query
end
--cerrar cursor
close cursorRecorrerTabla
deallocate cursorRecorrerTabla

0

아래 쿼리를 통해 찾을 수 있습니다.

 SELECT OBJECT_NAME (FK.referenced_object_id) 'Referenced Table', 
      OBJECT_NAME(FK.parent_object_id) 'Referring Table', FK.name 'Foreign Key', 
      COL_NAME(FK.referenced_object_id, FKC.referenced_column_id) 'Referenced Column',
      COL_NAME(FK.parent_object_id,FKC.parent_column_id) 'Referring Column'
     FROM sys.foreign_keys AS FK
             INNER JOIN sys.foreign_key_columns AS FKC 
                 ON FKC.constraint_object_id = FK.OBJECT_ID
     WHERE OBJECT_NAME (FK.referenced_object_id) = 'YourTableName'
     AND COL_NAME(FK.referenced_object_id, FKC.referenced_column_id) = 'YourColumnName'
     order by  OBJECT_NAME(FK.parent_object_id)

0

또한 시도하십시오.

EXEC sp_fkeys 'tableName', 'schemaName'

함께 sp_fkeys당신 PK 테이블 이름과 스키마뿐만 아니라 FK 테이블 이름과 스키마뿐만 아니라하여 결과를 필터링 할 수 있습니다. 링크


0

@BankZ가 가장 선호하는 답변

sp_help 'TableName'   

다른 스키마에 대한 추가

sp_help 'schemaName.TableName'   
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.