Làm cách nào tôi có thể liệt kê tất cả các khóa ngoại tham chiếu một bảng đã cho trong SQL Server?


736

Tôi cần xóa một bảng được tham chiếu cao trong cơ sở dữ liệu SQL Server. Làm thế nào tôi có thể nhận được một danh sách tất cả các ràng buộc khóa ngoài mà tôi sẽ cần phải xóa để bỏ bảng?

(Câu trả lời SQL tốt hơn là nhấp vào trong GUI của studio quản lý.)


Xem Cách viết ra tất cả các khóa ngoại của bảng để được trợ giúp. Cập nhật : Liên kết không còn khả dụng nhưng SQL có liên quan đã được sao chép dưới dạng câu trả lời cho câu hỏi liên quan. Bạn cũng có thể xem các phụ thuộc thông qua GUI.
Galkish

Câu trả lời:


1126

Không chắc chắn tại sao không ai đề xuất nhưng tôi sử dụng sp_fkeysđể truy vấn các khóa ngoại cho một bảng đã cho:

EXEC sp_fkeys 'TableName'

Bạn cũng có thể chỉ định lược đồ:

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

Không chỉ định lược đồ, các tài liệu nêu rõ như sau:

Nếu pktable_owner không được chỉ định, quy tắc hiển thị bảng mặc định của DBMS cơ bản được áp dụng.

Trong SQL Server, nếu người dùng hiện tại sở hữu một bảng có tên được chỉ định, các cột của bảng đó sẽ được trả về. Nếu pktable_owner không được chỉ định và người dùng hiện tại không sở hữu bảng có pktable_name được chỉ định, quy trình sẽ tìm một bảng có pktable_name được chỉ định thuộc sở hữu của chủ sở hữu cơ sở dữ liệu. Nếu một cái tồn tại, các cột của bảng đó được trả về.


41
Điều này không làm việc cho tôi trên cơ sở dữ liệu sql 2008 vì một số lý do. sp_help hiển thị các mối quan hệ, nhưng lệnh này sẽ không.
xương đòn

21
@tbone: Tôi có cùng một vấn đề, liên quan đến việc không chỉ định đầy đủ các tham số. Đưa ra bảng T, thuộc sở hữu của O, trong cơ sở dữ liệu D, bạn cần thực thi EXEC sp_fkeys \ @ pktable_name = 'T', \ @ pktable_owner = 'O', \ @ pktable_qualifier = 'D' Hãy thử nhìn vào đầu ra của EXEC sp_tables \ @ tên_bảng = 'T' để tìm ra các giá trị tham số nên là gì.
Mads Ravn

3
@JustinRusso Bạn có thể khắc phục điều này bằng cách tạo bảng, lưu kết quả vào bảng, sau đó chọn các cột cụ thể. Kiểm tra liên kết này cho một ví dụ :).
John Odom

3
Hoạt động tốt trong SSMS 2014. Cảm ơn.
À.

7
Nó đã được trả lời trong các bình luận ở trên: nhưng chỉ cho rõ ràng - EXEC sp_fkeys @pktable_name = N'Depidor ', @ pktable_owner = N'dbo'; msdn.microsoft.com/en-NZ/l Library / ms175090.aspx
Tejas Patel

233

Tôi sẽ sử dụng tính năng Lập biểu đồ cơ sở dữ liệu trong SQL Server Management Studio, nhưng vì bạn đã loại trừ điều đó - điều này hiệu quả với tôi trong SQL Server 2008 (không có năm 2005).

Để có danh sách tên bảng và cột giới thiệu ...

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

Để có được tên của các ràng buộc khóa ngoại

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
tuyệt vời, mặc dù được sử dụng tham chiếu_object_id thay vì cha mẹ. chọn tên riêng biệt từ sys.objects nơi object_id trong (chọn fk.constraint_object_id từ sys.foreign_key_columns như fk nơi fk.referenced_object_id = (chọn object_id từ sys.tables nơi tên = 'tablename'))
chillitom

4
Bạn có thể lấy tên của FK bằng cách thêm "object_name (ràng buộc_object_id)" vào lựa chọn của truy vấn đầu tiên.
sam yi

3
Bạn có thể lấy id đối tượng object_id ('TableOthersForeignKeyInto')
IvanH

189

Điều này mang lại cho bạn:

  • Bản thân FK
  • Lược đồ mà FK thuộc về
  • " Bảng tham chiếu " hoặc bảng có FK
  • " Cột tham chiếu " hoặc cột bên trong bảng tham chiếu trỏ đến FK
  • " Bảng tham chiếu " hoặc bảng có cột khóa mà FK của bạn đang trỏ đến
  • " Cột được tham chiếu " hoặc cột là khóa mà FK của bạn đang trỏ đến

Mã dưới đây:

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
Đây là câu trả lời tốt nhất trong ý kiến ​​của tôi nếu bạn muốn lọc kết quả sau đó.
Faliorn

Hoạt động tuyệt vời! Sẽ tốt hơn nữa nếu bạn: a) tiền tố tất cả các Tên cột với "Fk" / "Khóa"), b) hậu tố tất cả các Tên cột với "Tên", c) xóa dấu gạch dưới, d) thêm KeyTableSchemaName, e) thêm mặc định order by: KeyTableSchemaName, KeyTableName, KeyColumnName, FkTableSchemaName, FkTableName, FkName, và f) thay đổi thứ tự Cột thành: KeyTableSchemaName, KeyTableName, KeyColumnName, FkTableSchemaName, KeykName, FkTableName, Fk quy ước và d / e cho việc sử dụng có khả năng nhất (liệt kê những người phụ thuộc FK của a Table).
Tom

Đó là một câu trả lời tuyệt vời và truy vấn hữu ích. Cảm ơn bạn
Rich Dominelli

153

Thử cái này :

sp_help 'TableName'

2
Phương pháp trợ giúp tuyệt vời để biết nếu bạn đang khám phá db của mình một cách thủ công. Ngoài ra, nó hoạt động trên Azure SQL Server.
Pac0

48

Bạn cũng nên nhớ các tài liệu tham khảo đến các đối tượng khác.

Nếu bảng được tham chiếu nhiều bởi các bảng khác thì có lẽ nó cũng được tham chiếu nhiều bởi các đối tượng khác như khung nhìn, thủ tục được lưu trữ, hàm và hơn thế nữa.

Tôi thực sự khuyên dùng công cụ GUI như hộp thoại 'xem phụ thuộc' trong SSMS hoặc công cụ miễn phí như ApexQuery Search cho việc này vì việc tìm kiếm phụ thuộc trong các đối tượng khác có thể dễ bị lỗi nếu bạn chỉ muốn làm điều đó với SQL.

Nếu SQL là tùy chọn duy nhất bạn có thể thử làm như thế này.

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

Câu hỏi ban đầu được yêu cầu để có được một danh sách tất cả các khóa ngoại vào một bảng được tham chiếu cao để bảng có thể được gỡ bỏ.

Truy vấn nhỏ này trả về tất cả các lệnh 'thả khóa ngoại' cần thiết để thả tất cả các khóa ngoại vào một bảng cụ thể:

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'

Ví dụ đầu ra:

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

Bỏ qua mệnh đề WHERE để nhận các lệnh thả cho tất cả các khóa ngoại trong cơ sở dữ liệu hiện tại.


17

Đây là mã SQL tôi sẽ sử dụng.

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

Nó không đặc biệt rõ ràng về SQL, vì vậy hãy xem xét một ví dụ.

Vì vậy, giả sử tôi muốn bỏ Employeesbảng trong Northwindcơ sở dữ liệu yêu thích của Microsoft , nhưng SQL Server nói với tôi rằng một hoặc nhiều Khóa ngoại đang ngăn tôi làm điều này.

Lệnh SQL ở trên sẽ trả về các kết quả này ...

Khóa ngoại

Nó cho tôi thấy rằng có 3 Khóa ngoài tham chiếu Employeesbảng. Nói cách khác, tôi sẽ không được phép xóa (thả) bảng này cho đến khi ba Khóa ngoại này bị xóa lần đầu tiên.

Trong kết quả, hàng đầu tiên là cách hiển thị ràng buộc Khóa ngoài sau trong kết quả.

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

Cột thứ hai đến cuối cùng hiển thị lệnh SQL mà tôi sẽ cần sử dụng để xóa một trong các Khóa ngoại này, ví dụ:

ALTER TABLE [Employees] DROP CONSTRAINT [FK_Employees_Employees]

... và cột bên phải hiển thị SQL để tạo ...

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

Với tất cả các lệnh này, bạn có mọi thứ bạn cần để xóa Khóa ngoại liên quan để cho phép bạn xóa bảng, sau đó tạo lại chúng sau.

Phù. Hi vọng điêu nay co ich.


Sẽ rõ ràng hơn nếu bạn sử dụng nối bên trong và trên các mệnh đề thay vì nối chéo. Nhưng điều này là hữu ích không hơn không kém!
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

Đơn giản nhất là bằng cách sử dụng sys.forign_keys_columns trong SQL. Ở đây, bảng chứa các Id đối tượng của tất cả các khóa ngoại đã viết ID cột tham chiếu ID của chúng cũng như các cột và bảng tham chiếu. Vì Id không đổi, kết quả sẽ đáng tin cậy cho các sửa đổi tiếp theo trong Schema cũng như các bảng.

Truy vấn:

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

Chúng tôi cũng có thể thêm bộ lọc bằng cách sử dụng 'where'

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

Điều này là tuyệt vời khi bạn cần loại bỏ toàn bộ cấu trúc DB / bộ bảng được tham chiếu.
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

Tôi đang sử dụng tập lệnh này để tìm tất cả các chi tiết liên quan đến khóa ngoại. Tôi đang sử dụng THÔNG TIN.SCHema. Dưới đây là tập lệnh 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


5

Một số câu trả lời tốt ở trên. Nhưng tôi thích có câu trả lời với một truy vấn. Đoạn mã này được lấy từ sys.sp_helpconstraint (sys Proc)

Đó là cách Microsoft tìm kiếm nếu có các khóa ngoại liên quan đến tbl.

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

Câu trả lời sẽ như thế này: test_db_name.dbo.Account: FK_Account_Customer


3
Đây thực sự giống như 4 câu lệnh truy vấn riêng biệt ... điều này thực sự giống với một câu lệnh: 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'

Nếu bạn muốn lấy quan hệ khóa ngoại của tất cả các bảng loại trừ wheremệnh đề khác, hãy viết tablename của bạn thay vì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')

Điều này chỉ hiển thị mối quan hệ nếu các ràng buộc khóa ngoài. Cơ sở dữ liệu của tôi rõ ràng có trước ràng buộc FK. Một số bảng sử dụng kích hoạt để thực thi tính toàn vẹn tham chiếu và đôi khi không có gì ngoài một cột có tên tương tự để chỉ ra mối quan hệ (và hoàn toàn không tham chiếu).

May mắn thay, chúng ta có một cảnh đặt tên nhất quán để tôi có thể tìm thấy các bảng tham chiếu và các khung nhìn như thế này:

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

Tôi đã sử dụng lựa chọn này làm cơ sở để tạo một tập lệnh thực hiện những gì tôi cần làm trên các bảng liên quan.


3

Làm việc với những gì @Gishu đã làm tôi có thể tạo và sử dụng SQL sau trong SQL Server 2005

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;

Hiển thị tất cả các bảng, cột và tên khóa ngoài trong 1 truy vấn.


3

Xác định khóa chính và khóa duy nhất cho tất cả các bảng trong cơ sở dữ liệu ...

Điều này sẽ liệt kê tất cả các ràng buộc và cuối cùng, bạn có thể đặt các bộ lọc của mình

/* 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 xin vui lòng đọc thông qua - http://bloss.msdn.com/b/sqltips/archive/2005/09/16/469136.aspx


2
Điều này chứa quá nhiều thông tin cho câu hỏi. Bạn có thể bao gồm một số lời giải thích (và loại bỏ mã bổ sung) để chỉ trả lời câu hỏi, xin vui lòng? Bạn đã đăng câu trả lời chính xác này cho hai câu hỏi khác nhau và mỗi câu hỏi chỉ cần một phần của câu trả lời này.
Andrew Barber

2
Tôi đã chỉnh sửa câu trả lời - Xác định khóa chính và khóa duy nhất cho tất cả các bảng trong cơ sở dữ liệu ... Tôi nghĩ rằng câu trả lời ở đây là phù hợp, vì câu hỏi dành cho tất cả các tài liệu tham khảo.
dekdev

3

Tôi đã sử dụng cái này từ năm 2008 trở lên. Nó tương tự như một số giải pháp khác được liệt kê nhưng, tên trường được đặt đúng để xử lý các đối chiếu trường hợp cụ thể (LatBin). Ngoài ra, bạn có thể cung cấp cho nó một tên bảng duy nhất và chỉ lấy thông tin cho bảng đó.

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

Có cách lấy số lượng tất cả trách nhiệm cho Id được chọn. Chỉ cần thay đổi giá trị @dbTableName, giá trị @dbRowId và loại của nó (nếu int bạn cần xóa '' trong dòng số 82 (..SET @Query = ..)). Thưởng thức.

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

Máy chủ Mysql có information_schema.REFERENTIAL_CONSTRAINTSbảng FYI, bạn có thể lọc nó theo tên bảng hoặc tên bảng được tham chiếu.


2

Danh sách tất cả các khóa ngoại tham chiếu một bảng đã cho trong SQL Server:

Bạn có thể lấy tên bảng tham chiếu và tên cột thông qua truy vấn sau ...

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'

Và theo dõi ảnh chụp màn hình để bạn hiểu ...

nhập mô tả hình ảnh ở đây


1

Điều này nhận được bất kỳ khóa ngoại liên quan đến bảng đã chọn. * Giả sử định dạng _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 )

Đây là một hình thức tổng quát hơn:

 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

Giải pháp sau đây phù hợp với tôi:

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

Bạn có thể tìm thấy thông qua truy vấn dưới đây:

 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

Cũng cố gắng.

EXEC sp_fkeys 'tableName', 'schemaName'

với sp_fkeysbạn có thể lọc kết quả bằng không chỉ tên bảng và lược đồ pk mà còn với lược đồ và tên bảng fk. liên kết


0

Câu trả lời thích hợp nhất của @BankZ

sp_help 'TableName'   

ngoài ra cho các lược đồ khác nhau

sp_help 'schemaName.TableName'   
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.