Jak mogę się dowiedzieć, jakie ograniczenie KLUCZ OBCY odwołuje się do tabeli w programie SQL Server?

122

Próbuję usunąć tabelę, ale pojawia się następujący komunikat:

Msg 3726, poziom 16, stan 1, wiersz 3
Nie można usunąć obiektu „dbo.UserProfile”, ponieważ odwołuje się do niego ograniczenie FOREIGN KEY.
Msg 2714, poziom 16, stan 6, wiersz 2
W bazie danych istnieje już obiekt o nazwie „UserProfile”.

Rozejrzałem się po SQL Server Management Studio, ale nie mogę znaleźć ograniczenia. Jak mogę znaleźć ograniczenia klucza obcego?

marc_s
źródło
2
Lubię sp_help 'dbo.TableName' Zobacz tutaj, aby uzyskać więcej sposobów: stackoverflow.com/questions/483193/ ...
Mark Boltuc
2
Worth noticing:Odpowiedź @LittleSweetSeas zwróci informacje o kluczach obcych dla danej tabeli , do której się odwołujemy , natomiast szczegóły odpowiedzi @ Gayathri-Varma dla danej tabeli nadrzędnej . Oba są przydatne w innym kontekście i obaj wygrywają swój własny wyścig :-)
Izhar Aazmi

Odpowiedzi:

225

Oto ona:

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

W ten sposób otrzymasz odwołanie do tabeli i nazwę kolumny.

Edytowano, aby używać sys.tables zamiast ogólnych sys.objects zgodnie z sugestią komentarza. Dzięki, marc_s

LittleSweetSeas
źródło
Powinieneś raczej używać bardziej skoncentrowanego sys.tablesniżsys.objects
marc_s
@marc_s: Dziękuję, ale czy możesz opublikować przykład? AFAIK w sys.tables, nie mam referencji FK
LittleSweetSeas
3
Chodziło mi o to: po prostu zastąpić INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_idzINNER JOIN sys.tables t ON t.OBJECT_ID = fc.referenced_object_id
marc_s
@LittleSweetSeas Uruchomiłem powyższe zapytanie nadal nie otrzymuję nazwy obiektu i nazwy kolumny dla tabeli, która miała ograniczenie klucza obcego
Smart003
Możesz wzbogacić swój wybór o trochę więcej informacji: SELECT f.name ConstraintName, f.type_desc ConstraintType, OBJECT_NAME (f.parent_object_id) ConstrainedTable, COL_NAME (fc.parent_object_id, fc.parent_column_id) ConstrainedColumn, OBJECT_NAME (f.referenced_obid) , COL_NAME (fc.referenced_object_id, fc.referenced_column_id) ReferencedColumn
DocOc
75

Innym sposobem jest sprawdzenie wyników

sp_help 'TableName'

(lub po prostu zaznacz cytowaną nazwę TableName i naciśnij ALT + F1)

Z biegiem czasu zdecydowałem się po prostu zawęzić odpowiedź. Poniżej znajduje się zrzut ekranu przedstawiający wyniki sp_help. W tym przykładzie wykorzystano bazę danych AdventureWorksDW2012. Jest tam wiele dobrych informacji, a to, czego szukamy, znajduje się na samym końcu - zaznaczone na zielono:

wprowadź opis obrazu tutaj

Vladislav
źródło
3
+1 Daje to wiele pomocnych informacji i pokazuje klucze obce na dole wyniku
Hux.
1
To daje mi dużo informacji w najmniejszej liczbie wierszy kodu
Rennish Joseph
To najfajniejszy skrót! Całkowicie bije Ctl-R, aby odświeżyć schemat!
Mr. Young
Odśwież lokalną pamięć podręczną InteliSense = Ctrl + Shift + R; Ctrl + R = pokaż / ukryj okienko wyników (lub przynajmniej są to moje ustawienia domyślne dla SSMS2008 i SSMS2014)
Vladislav
44

Spróbuj tego

SELECT
  object_name(parent_object_id) ParentTableName,
  object_name(referenced_object_id) RefTableName,
  name 
FROM sys.foreign_keys
WHERE parent_object_id = object_id('Tablename')
Gayathri L.
źródło
1
Krótka i elegancka, a na mnie działa! Jedyną rzeczą jest to, że namezwracana wartość jest nazwą wewnętrzną (myślę), a nie rzeczywistą nazwą kolumny w tabeli nadrzędnej. Jakiś sposób to naprawić?
Hamman Samuel,
Widzę tutaj, ParentTableNameże zawsze byłby taki sam jak dany ' Tablename' w klauzuli where (jeśli jest uwzględniony). Może to być zamierzone i będzie bardziej przydatne w przypadku zapytań dotyczących więcej niż jednej tabeli.
Izhar Aazmi
28

Uznałem, że ta odpowiedź jest dość prosta i załatwiłem to, czego potrzebowałem: https://stackoverflow.com/a/12956348/652519

Podsumowanie z linku, użyj tego zapytania:

EXEC sp_fkeys 'TableName'

Szybko i prosto. Udało mi się dość szybko zlokalizować wszystkie tabele kluczy obcych, odpowiednie kolumny i nazwy kluczy obcych 15 tabel.

Jak zauważył @mdisibio poniżej, oto link do dokumentacji, która zawiera szczegółowe informacje o różnych parametrach, których można użyć: https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp- fkeys-transact-sql

Michael
źródło
1
Jest pięć innych parametrów do filtrowania, z których najbardziej użytecznym jest drugi, w którym można określić inny niż domyślny schemat, np.EXEC sp_fkeys 'Payroll', 'accounting'
mdisibio
8

Używam tego skryptu, aby znaleźć wszystkie szczegóły dotyczące klucza obcego. Używam INFORMATION.SCHEMA. Poniżej znajduje się skrypt 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
Anvesh
źródło
2
Szukałem sposobu, aby zobaczyć kolumny, które są obcymi kluczami i powiązane tabele, do których odwołuje się kolumna, a to ładnie podsumowuje. Dzięki!
Nate Kindrew
Brakowało niektórych kluczy obcych na niektórych moich stołach, podczas gdy odpowiedź @LittleSweetSeas pokazała je
Seafish
7

jeśli chcesz przejść przez SSMS w oknie eksploratora obiektów, kliknij prawym przyciskiem myszy obiekt, który chcesz upuścić, zobacz zależności.

Luis LL
źródło
7

Oto najlepszy sposób na znalezienie powiązania klucza obcego we wszystkich bazach danych.

exec sp_helpconstraint 'Table Name'

i jeszcze jeden sposób

select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME='Table Name'
--and left(CONSTRAINT_NAME,2)='FK'(If you want single key)
Vinoth_S
źródło
To rozwiązanie exec sp_helpconstraint 'Table Name'jako jedyne zwraca dla mnie jakiekolwiek wiersze. Jednak nazwa przeszkody jest bełkotem. PRIMARY KEY (clustered) PK__org_soft__3213E83FE6B07364
Tor
5
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;
Murali_DBA
źródło
1

- Poniższe informacje mogą dać ci więcej tego, czego szukasz:

create Procedure spShowRelationShips 
( 
    @Table varchar(250) = null,
    @RelatedTable varchar(250) = null
)
as
begin
    if @Table is null and @RelatedTable is null
        select  object_name(k.constraint_object_id) ForeginKeyName, 
                object_name(k.Parent_Object_id) TableName, 
                object_name(k.referenced_object_id) RelatedTable, 
                c.Name RelatedColumnName,  
                object_name(rc.object_id) + '.' + rc.name RelatedKeyField
        from sys.foreign_key_columns k
        left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
        left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
        order by 2,3

    if @Table is not null and @RelatedTable is null
        select  object_name(k.constraint_object_id) ForeginKeyName, 
                object_name(k.Parent_Object_id) TableName, 
                object_name(k.referenced_object_id) RelatedTable, 
                c.Name RelatedColumnName,  
                object_name(rc.object_id) + '.' + rc.name RelatedKeyField
        from sys.foreign_key_columns k
        left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
        left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
        where object_name(k.Parent_Object_id) =@Table
        order by 2,3

    if @Table is null and @RelatedTable is not null
        select  object_name(k.constraint_object_id) ForeginKeyName, 
                object_name(k.Parent_Object_id) TableName, 
                object_name(k.referenced_object_id) RelatedTable, 
                c.Name RelatedColumnName,  
                object_name(rc.object_id) + '.' + rc.name RelatedKeyField
        from sys.foreign_key_columns k
        left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
        left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
        where object_name(k.referenced_object_id) =@RelatedTable
        order by 2,3



end
Mikrofon
źródło
1

Możesz również zwrócić wszystkie informacje na temat, Foreign Keysdostosowując odpowiedź @LittleSweetSeas:

SELECT 
   OBJECT_NAME(f.parent_object_id) ConsTable,
   OBJECT_NAME (f.referenced_object_id) refTable,
   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
order by
ConsTable
użytkownik1
źródło
1

W SQL Server Management Studio wystarczy kliknąć prawym przyciskiem myszy tabelę w eksploratorze obiektów i wybrać opcję „Wyświetl zależności”. To dałoby dobry punkt wyjścia. Przedstawia tabele, widoki i procedury odwołujące się do tabeli.

Darrel Lee
źródło
0

spróbuj następującego zapytania.

select object_name(sfc.constraint_object_id) AS constraint_name,
       OBJECT_Name(parent_object_id) AS table_name ,
       ac1.name as table_column_name,
       OBJECT_name(referenced_object_id) as reference_table_name,      
       ac2.name as reference_column_name
from  sys.foreign_key_columns sfc
join sys.all_columns ac1 on (ac1.object_id=sfc.parent_object_id and ac1.column_id=sfc.parent_column_id)
join sys.all_columns ac2 on (ac2.object_id=sfc.referenced_object_id and ac2.column_id=sfc.referenced_column_id) 
where sfc.parent_object_id=OBJECT_ID(<main table name>);

da to ograniczenie nazwa_kolumny, nazwy_kolumn, które będą się odnosić, oraz tabele, które będą zależne od ograniczenia, będą tam.

Smart003
źródło
0

Możesz użyć tego zapytania, aby wyświetlić Foreign keyconstaraints:

SELECT
K_Table = FK.TABLE_NAME,
FK_Column = CU.COLUMN_NAME,
PK_Table = PK.TABLE_NAME,
PK_Column = PT.COLUMN_NAME,
Constraint_Name = C.CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
INNER JOIN (
SELECT i1.TABLE_NAME, i2.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
) PT ON PT.TABLE_NAME = PK.TABLE_NAME
---- optional:
ORDER BY
1,2,3,4
WHERE PK.TABLE_NAME='YourTable'

Zaczerpnięte z http://blog.sqlauthority.com/2006/11/01/sql-server-query-to-display-foreign-key-relationships-and-name-of-the-constraint-for-each-table- w bazie danych /

użytkownik1
źródło
0

Najłatwiejszym sposobem na zdobycie Primary Keyi Foreign Keyna stolik jest:

/*  Get primary key and foreign key for a table */
USE DatabaseName;

SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE CONSTRAINT_NAME LIKE 'PK%' AND
TABLE_NAME = 'TableName'

SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE CONSTRAINT_NAME LIKE 'FK%' AND
TABLE_NAME = 'TableName'
Ashraf Abusada
źródło
0

W Eksploratorze obiektów rozwiń tabelę i rozwiń Klucze:

wprowadź opis obrazu tutaj

Hank Z
źródło