Bagaimana saya bisa mendaftar semua kunci asing referensi tabel yang diberikan dalam SQL Server?

736

Saya perlu menghapus tabel yang sangat direferensikan dalam database SQL Server. Bagaimana saya bisa mendapatkan daftar semua batasan kunci asing yang perlu saya hapus untuk menjatuhkan tabel?

(SQL menjawab lebih baik daripada mengklik di GUI studio manajemen.)

chillitom
sumber
Lihat Cara Menghapus Semua Kunci Asing dari Tabel untuk bantuan. Pembaruan : Tautan tidak lagi tersedia tetapi SQL yang relevan disalin sebagai jawaban untuk pertanyaan terkait. Anda juga dapat melihat dependensi melalui GUI.
Galwegian

Jawaban:

1126

Tidak yakin mengapa tidak ada yang menyarankan tetapi saya gunakan sp_fkeysuntuk menanyakan kunci asing untuk tabel yang diberikan:

EXEC sp_fkeys 'TableName'

Anda juga dapat menentukan skema:

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

Tanpa menentukan skema, dokumen menyatakan sebagai berikut:

Jika pktable_owner tidak ditentukan, aturan visibilitas tabel default dari DBMS yang mendasarinya berlaku.

Di SQL Server, jika pengguna saat ini memiliki tabel dengan nama yang ditentukan, kolom tabel itu dikembalikan. Jika pktable_owner tidak ditentukan dan pengguna saat ini tidak memiliki tabel dengan pktable_name yang ditentukan, prosedur mencari tabel dengan pktable_name yang ditentukan yang dimiliki oleh pemilik database. Jika ada, kolom tabel itu dikembalikan.

Recep
sumber
41
Ini tidak berfungsi untuk saya pada database 2008 sql untuk beberapa alasan. sp_help menunjukkan relasi, tetapi perintah ini tidak akan.
Tulang
21
@ tulang: Saya punya masalah yang sama, yang terkait dengan tidak sepenuhnya menentukan parameter. Diberikan tabel T, dimiliki oleh O, dalam database D Anda perlu menjalankan EXEC sp_fkeys \ @ pktable_name = 'T', \ @ pktable_owner = 'O', \ @ pktable_qualifier = 'D' Coba lihat output dari EXEC sp_tables \ @ table_name = 'T' untuk mencari tahu nilai parameter apa yang seharusnya.
Mads Ravn
3
@JustinRusso Anda dapat menyiasatinya dengan membuat tabel, menyimpan hasilnya ke dalam tabel, lalu pilih kolom tertentu. Lihat tautan ini sebagai contoh :).
John Odom
3
Berfungsi dengan baik di SSMS 2014. Terima kasih.
AH.
7
Sudah dijawab dalam komentar di atas: tetapi hanya untuk kejelasan - EXEC sp_fkeys @pktable_name = N'Department ', @ pktable_owner = N'dbo'; msdn.microsoft.com/en-NZ/library/ms175090.aspx
Tejas Patel
233

Saya akan menggunakan fitur Database Diagramming di SQL Server Management Studio, tetapi karena Anda mengesampingkannya - ini bekerja untuk saya di SQL Server 2008 (tidak punya 2005).

Untuk mendapatkan daftar nama tabel dan kolom referensi ...

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

Untuk mendapatkan nama batasan kunci asing

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')
)
Gishu
sumber
4
hebat, meskipun digunakan referenced_object_id bukan orangtua. pilih nama yang berbeda dari sys.objects di mana object_id di (pilih fk.constraint_object_id dari sys.foreign_key_columns sebagai fk mana fk.referenced_object_id = (pilih object_id dari sys.tables di mana nama = 'tablename'))
chillitom
4
Anda bisa mendapatkan nama FK dengan menambahkan "object_name (constraint_object_id)" ke pemilihan kueri pertama.
sam yi
3
Anda bisa mendapatkan objek id object_id ('TableOthersForeignKeyInto')
IvanH
189

Ini memberi Anda:

  • FK itu sendiri
  • Skema yang menjadi milik FK
  • " Tabel referensi " atau tabel yang memiliki FK
  • " Kolom referensi " atau kolom di dalam tabel referensi yang menunjuk ke FK
  • " Tabel yang direferensikan " atau tabel yang memiliki kolom kunci yang ditunjuk oleh FK Anda
  • " Kolom yang direferensikan " atau kolom yang merupakan kunci yang ditunjuk oleh FK Anda

Kode di bawah ini:

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
Gustavo Rubio
sumber
13
Ini adalah jawaban terbaik menurut pendapat saya jika Anda ingin menyaring hasilnya sesudahnya.
Faliorn
Bagus sekali! Akan lebih baik jika Anda: a) awali semua Nama Kolom dengan "Fk" / "Kunci"), b) sufiks semua Nama Kolom dengan "Nama", c) hapus garis bawah, d) tambahkan KeyTableSchemaName, e) tambahkan default order by: KeyTableSchemaName, KeyTableName, KeyColNameName, FkTableSchemaName, FkTableName, FkName, dan f) ubah urutan Kolom ke: KeyTableSchemaName, KeyTableName, KeyColNameName, FkTableSchemaName, FkTame / FkTotal, a konvensi dan d / e untuk penggunaan yang paling mungkin (daftar tanggungan FK a Table).
Tom
Jawaban yang sangat bagus dan pertanyaan yang bermanfaat. Terima kasih
Rich Dominelli
153

Coba ini :

sp_help 'TableName'
BankZ
sumber
2
Metode pembantu yang bagus untuk mengetahui apakah Anda menjelajahi db Anda secara manual. Juga, ini berfungsi pada Azure SQL Server.
Pac0
48

Anda juga harus memikirkan referensi ke objek lain.

Jika tabel sangat dirujuk oleh tabel lain selain itu mungkin juga sangat direferensikan oleh objek lain seperti tampilan, prosedur tersimpan, fungsi dan banyak lagi.

Saya sangat merekomendasikan alat GUI seperti dialog 'lihat dependensi' di SSMS atau alat gratis seperti ApexSQL Search untuk ini karena mencari dependensi pada objek lain dapat menjadi rawan kesalahan jika Anda ingin melakukannya hanya dengan SQL.

Jika SQL adalah satu-satunya opsi yang dapat Anda coba lakukan seperti ini.

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%'
Mspaja
sumber
21

Pertanyaan awal diminta untuk memasukkan daftar semua kunci asing ke dalam tabel yang sangat direferensikan sehingga tabel tersebut dapat dihapus.

Kueri kecil ini mengembalikan semua perintah 'jatuhkan kunci asing' yang diperlukan untuk memasukkan semua kunci asing ke dalam tabel tertentu:

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'

Contoh output:

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

Hapus klausa WHERE-untuk mendapatkan perintah drop untuk semua kunci asing di database saat ini.

JS
sumber
17

Inilah kode SQL yang akan saya gunakan.

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

Ini tidak terlalu jelas SQL, jadi mari kita lihat sebuah contoh.

Jadi, seandainya saya ingin menjatuhkan Employeestabel dalam Northwinddatabase tercinta Microsoft , tetapi SQL Server mengatakan kepada saya bahwa satu atau lebih Kunci Asing mencegah saya melakukan ini.

Perintah SQL di atas akan mengembalikan hasil ini ...

Kunci Asing

Ini menunjukkan kepada saya bahwa ada 3 Kunci Asing yang merujuk Employeestabel. Dengan kata lain, saya tidak akan diizinkan untuk menghapus (drop) tabel ini sampai ketiga Kunci Asing ini pertama kali dihapus.

Dalam hasil, baris pertama adalah bagaimana batasan Kunci Asing berikut akan ditampilkan dalam hasil.

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

Kolom kedua ke terakhir menunjukkan perintah SQL yang saya perlukan untuk menghapus salah satu kunci asing ini, misalnya:

ALTER TABLE [Employees] DROP CONSTRAINT [FK_Employees_Employees]

... dan kolom sebelah kanan menunjukkan SQL untuk membuatnya ...

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

Dengan semua perintah ini, Anda memiliki semua yang Anda butuhkan untuk menghapus Kunci Asing yang relevan untuk memungkinkan Anda menghapus tabel, kemudian membuatnya kembali nanti.

Fiuh. Semoga ini membantu.

Mike Gledhill
sumber
Akan lebih jelas jika Anda menggunakan klausa dalam dan klausa alih-alih silang. Tapi ini sangat membantu!
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
Omu
sumber
15

Yang paling sederhana adalah dengan menggunakan sys.foreign_keys_columns dalam SQL. Di sini tabel berisi id Objek dari semua kunci asing yang menggunakan ID kolom yang direferensikan, ID Tabel yang Dirujuk serta Kolom dan Tabel Referensi. Karena Id tetap konstan, hasilnya akan dapat diandalkan untuk modifikasi lebih lanjut dalam Skema dan juga tabel.

Pertanyaan:

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

Kami juga dapat menambahkan filter dengan menggunakan 'di mana'

WHERE OBJECT_NAME(fkeys.parent_object_id) = 'table_name' AND 
OBJECT_SCHEMA_NAME(fkeys.parent_object_id) = 'schema_name'
Garuda Prasad K
sumber
Ini bagus untuk saat Anda perlu menghapus seluruh konstruksi / set tabel referensi 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')
Vishal Gajjar
sumber
11

Saya menggunakan skrip ini untuk menemukan semua detail yang terkait dengan kunci asing. Saya menggunakan INFORMATION.SCHEMA. Di bawah ini adalah Skrip 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
Landasan
sumber
8

Pertama

EXEC sp_fkeys 'Table', 'Schema'

Kemudian gunakan NimbleText untuk bermain dengan hasil Anda

irfandar
sumber
5

Beberapa jawaban bagus di atas. Tapi saya lebih suka memiliki jawaban dengan satu permintaan. Bagian kode ini diambil dari sys.sp_helpconstraint (sys proc)

Itulah cara Microsoft mencari jika ada kunci asing yang terkait dengan 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

Jawabannya akan terlihat seperti ini: test_db_name.dbo.Account: FK_Account_Customer

Mark Varnas
sumber
3
Ini sebenarnya seperti 4 pernyataan permintaan terpisah ... ini melakukan hal yang sama secara efektif dalam satu pernyataan: 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'

Jika Anda ingin mendapatkan hubungan kunci asing dari semua tabel mengecualikan whereklausa lain menulis tablename Anda, bukantablename

Membelok
sumber
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')

Ini hanya menunjukkan hubungan jika kendala kunci asing. Database saya tampaknya mendahului kendala FK. Beberapa tabel menggunakan pemicu untuk menegakkan integritas referensial, dan kadang-kadang tidak ada yang lain kecuali kolom yang sama namanya untuk menunjukkan hubungan (dan tidak ada integritas referensial sama sekali).

Untungnya, kami memiliki adegan penamaan yang konsisten sehingga saya dapat menemukan tabel referensi dan tampilan seperti ini:

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

Saya menggunakan pilih ini sebagai dasar untuk menghasilkan skrip yang melakukan apa yang perlu saya lakukan pada tabel terkait.

Darrel Lee
sumber
3

Bekerja dari apa yang dilakukan @Gishu, saya dapat membuat dan menggunakan SQL berikut di 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;

Yang menampilkan tabel, kolom, dan nama kunci asing semua dalam 1 permintaan.

Badai badai
sumber
3

Menentukan kunci primer dan kunci unik untuk semua tabel dalam database ...

Ini harus mencantumkan semua kendala dan pada akhirnya Anda dapat menempatkan filter Anda

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

Untuk referensi, silakan baca - http://blogs.msdn.com/b/sqltips/archive/2005/09/16/469136.aspx

dekdev
sumber
2
Ini mengandung terlalu banyak informasi untuk pertanyaan yang diajukan. Bisakah Anda memasukkan beberapa penjelasan (dan menghapus kode tambahan) untuk hanya menjawab pertanyaan? Anda memposting jawaban yang tepat untuk dua pertanyaan berbeda, dan masing-masing hanya membutuhkan bagian dari jawaban ini.
Andrew Barber
2
Saya mengedit jawabannya - Menentukan kunci primer dan kunci unik untuk semua tabel dalam database ... Saya pikir di sini jawabannya tepat, karena pertanyaannya adalah untuk semua referensi.
dekdev
3

Saya telah menggunakan ini pada 2008 ke atas. Ini mirip dengan beberapa solusi lain yang terdaftar, tetapi, nama bidangnya cocok untuk menangani kumpulan kasus spesifik (LatBin). Selain itu, Anda bisa memberinya satu nama tabel dan mengambil hanya info untuk tabel itu.

-->>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
Steve Mangiameli
sumber
2

Ada cara menghitung semua tanggung jawab untuk Id yang dipilih. Ubah saja nilai @dbTableName, nilai @dbRowId dan jenisnya (jika int Anda perlu menghapus '' pada baris no 82 (..SET @SQL = ..)). Nikmati.

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
MENGAKUI
sumber
2

Server Mysql memiliki information_schema.REFERENTIAL_CONSTRAINTStabel FYI, Anda dapat memfilternya berdasarkan nama tabel atau nama tabel yang direferensikan.

David
sumber
2

Daftar semua kunci asing referensi tabel yang diberikan dalam SQL Server:

Anda bisa mendapatkan nama tabel referensi dan nama kolom melalui kueri berikut ...

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'

Dan screenshot berikut untuk pengertian Anda ...

masukkan deskripsi gambar di sini

Manish Kumar Gurjar
sumber
1

Ini mendapatkan kunci asing apa pun yang melibatkan tabel yang dipilih. * Mengasumsikan format _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 )

Ini adalah bentuk yang lebih umum:

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

sumber
1

Solusi berikut ini berfungsi untuk saya:

--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
Jorge Santos Neill
sumber
0

Anda dapat menemukan melalui kueri di bawah ini:

 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)
Dilip Oganiya
sumber
0

Juga coba.

EXEC sp_fkeys 'tableName', 'schemaName'

dengan sp_fkeysAnda dapat memfilter hasilnya dengan tidak hanya nama dan skema tabel pk tetapi juga dengan nama dan skema tabel fk. tautan

Hossein Narimani Rad
sumber
0

Jawaban yang paling disukai oleh @BankZ

sp_help 'TableName'   

tambahan untuk skema yang berbeda

sp_help 'schemaName.TableName'   
Knight Fighter
sumber