Ten artykuł oferuje siedem sposobów na zwrócenie wszystkich tabel, które mają klucze obce w bazie danych SQL Server.
Każda tabela jest zwracana tylko raz, niezależnie od tego, ile może mieć kluczy obcych. Różni się to od zwracania wszystkich kluczy obcych wraz z ich tabelami. Jeśli chcesz to zrobić, zobacz 11 sposobów zwracania kluczy obcych w SQL Server.
Wszystkie przykłady tutaj wysyłają zapytanie do tej samej bazy danych, a zatem zwracają ten sam wynik.
Opcja 1 – OBJECTPROPERTY() z sys.tables
Pierwsza opcja to użycie OBJECTPROPERTY()
funkcja podczas odpytywania sys.tables
widok systemu.
Ta funkcja akceptuje TableHasForeignKey
argumentem, który będzie miał wartość 1
lub 0
(lub NULL
). Jeśli to 1
, oznacza to, że tabela ma klucz obcy. Wartość 0
oznacza, że nie ma żadnych kluczy obcych. Dlatego możemy użyć tego w WHERE
klauzula zwracająca tylko te tabele, w których TableHasForeignKey
jest ustawiony na 1
.
SELECT SCHEMA_NAME(schema_id) AS [Schema], nazwa AS [Table]FROM sys.tablesWHERE OBJECTPROPERTY(object_id, 'TableHasForeignKey') =1ORDER BY [Schema], [Table];
Wynik:
+----------+---------+| Schemat | Tabela ||----------+---------|| dbo | Albumy || dbo | Artyści |+----------+---------+
Opcja 2 – OBJECTPROPERTY() z INFORMATION_SCHEMA.TABLES
W tym przykładzie użyto OBJECTPROPERTY()
podczas zapytania INFORMATION_SCHEMA.TABLES
widok systemu.
SELECT TABLE_SCHEMA, TABLE_NAMEFROM INFORMATION_SCHEMA.TABLESWHERE OBJECTPROPERTY(OBJECT_ID(CONCAT(TABLE_SCHEMA, '.', TABLE_NAME))),'TableHasForeignKey') =1 ANDTABLE_TYPE='BASE TABLE'ORDER BY TABLE_SCHEMA;Wynik:
+----------------+--------------+| TABLE_SCHEMA | TABLE_NAME ||----------------+---------------|| dbo | Albumy || dbo | Artyści |+----------------+--------------+
Opcja 3 – OBJECTPROPERTY() z sys.objects
Oto kolejna opcja, która używa OBJECTPROPERTY()
. Tym razem używam go podczas odpytywania sys.objects
widok systemu.
SELECT SCHEMA_NAME(schema_id) AS [Schema], name AS [Table]FROM sys.objects WHERE type ='U'AND OBJECTPROPERTY(OBJECT_ID(CONCAT(SCHEMA_NAME(schema_id), '.', name)) 'TableHasForeignKey ') =1ORDER BY [Schema], [Tabela]
Wynik:
+----------+---------+| Schemat | Tabela ||----------+---------|| dbo | Albumy || dbo | Artyści |+----------+---------+
Opcja 4 – INFORMATION_SCHEMA.TABLE_CONSTRAINTS z DISTINCT
Oto przykład, który wysyła zapytanie do INFORMATION_SCHEMA.TABLE_CONSTRAINTS
widok systemu, w którym typem ograniczenia jest FOREIGN KEY
. W tym przypadku również używam DISTINCT
klauzuli, aby zapobiec wielokrotnemu zwracaniu tabel, jeśli mają więcej niż jeden klucz obcy.
SELECT DISTINCT CONSTRAINT_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTSWHERE CONSTRAINT_TYPE ='KLUCZ OBCY';
Wynik:
+---------------------+--------------+| CONSTRAINT_SCHEMA | TABLE_NAME ||---------------------+---------------|| dbo | Albumy || dbo | Artyści |+---------------------+--------------+
Oto, co się stanie, jeśli usunę DISTINCT
klauzula:
SELECT CONSTRAINT_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTSWHERE CONSTRAINT_TYPE ='KLUCZ OBCY';
Wynik:
+---------------------+--------------+| CONSTRAINT_SCHEMA | TABLE_NAME ||---------------------+---------------|| dbo | Albumy || dbo | Albumy || dbo | Artyści |+---------------------+--------------+
W tym przypadku Albums
tabela ma dwa klucze obce, więc otrzymuję dwa wiersze dla tej jednej tabeli.
Opcja 5 – sys.foreign_keys z DISTINCT
Oto kolejny przykład, który używa DISTINCT
klauzula, ale tym razem pytam o sys.foreign_keys
widok systemu.
SELECT DISTINCT OBJECT_SCHEMA_NAME(fk.parent_object_id) AS [Schema], OBJECT_NAME(fk.parent_object_id) AS [Tabela]FROM sys.foreign_keys AS fkORDER BY [Schema], [Tabela];
Wynik:
+----------+---------+| Schemat | Tabela ||----------+---------|| dbo | Albumy || dbo | Artyści |+----------+---------+
I tutaj jest bez DISTINCT
klauzula:
SELECT OBJECT_SCHEMA_NAME(fk.parent_object_id) AS [Schema], OBJECT_NAME(fk.parent_object_id) AS [Tabela]FROM sys.foreign_keys AS fkORDER BY [Schema], [Tabela];
Wynik:
+----------+---------+| Schemat | Tabela ||----------+---------|| dbo | Albumy || dbo | Albumy || dbo | Artyści |+----------+---------+
Opcja 6 – sys.foreign_keys z GROUP BY
Ten jest podobny do poprzedniego przykładu, ponieważ wysyła zapytanie do sys.foreign_keys
widok systemu. Różnica polega na tym, że zamiast używać DISTINCT
klauzula, używa GROUP BY
zamiast tego.
SELECT OBJECT_SCHEMA_NAME(fk.parent_object_id) AS [Schema], OBJECT_NAME(fk.parent_object_id) AS [Tabela]FROM sys.foreign_keys AS fkGROUP BY OBJECT_SCHEMA_NAME(fk.parent_object_id), OBJECT_NAME>(Wynik:
+----------+---------+| Schemat | Tabela ||----------+---------|| dbo | Albumy || dbo | Artyści |+----------+---------+Opcja 7 – OBJECTPROPERTYEX()
Ten przykład może podwajać poprzednie przykłady, ale nadal warto o nim wspomnieć.
Dowolny z poprzednich przykładów, w których użyto
OBJECTPROPERTY()
funkcja, może być łatwo przepisana do użyciaOBJECTPROPERTYEX()
funkcjonować. Ta funkcja jest w zasadzie rozszerzeniemOBJECTPROPERTY()
, i robi wszystkoOBJECTPROPERTY()
robi i więcej.Mogę więc przepisać pierwszy przykład na tej stronie w następujący sposób:
SELECT SCHEMA_NAME(schema_id) AS [Schema], nazwa AS [Table]FROM sys.tablesWHERE OBJECTPROPERTYEX(object_id, 'TableHasForeignKey') =1ORDER BY [Schema], [Table];Wynik:
+----------+---------+| Schemat | Tabela ||----------+---------|| dbo | Albumy || dbo | Artyści |+----------+---------+Jedną z różnic, o której powinieneś wiedzieć, jest to, że te dwie funkcje zwracają różne typy zwracanych.
OBJECTPROPERTY()
zwraca int natomiastOBJECTPROPERTYEX()
zwraca sql_variant typ.