Как узнать, какое ограничение FOREIGN KEY ссылается на таблицу в SQL Server?

122

Я пытаюсь удалить таблицу, но получаю следующее сообщение:

Msg 3726, уровень 16, состояние 1, строка 3
Не удалось удалить объект dbo.UserProfile, поскольку на него ссылается ограничение FOREIGN KEY.
Msg 2714, уровень 16, состояние 6, строка 2
В базе данных уже есть объект с именем «UserProfile».

Я осмотрелся с помощью SQL Server Management Studio, но не могу найти ограничение. Как узнать ограничения внешнего ключа?

marc_s
источник
2
Мне нравится sp_help 'dbo.TableName' Дополнительные способы см. Здесь: stackoverflow.com/questions/483193/…
Марк Болтук,
2
Worth noticing:Ответ от @LittleSweetSeas вернет информацию о внешних ключах для данной ссылочной таблицы , однако детали ответа @ Gayathri-Varma для данной родительской таблицы . Оба они полезны в разных условиях и оба выигрывают свои гонки :-)
Ижар Аазми

Ответы:

225

Вот:

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'

Таким образом вы получите справочную таблицу и имя столбца.

Отредактировано для использования sys.tables вместо общих sys.objects в соответствии с предложением комментария. Спасибо, marc_s

LittleSweetSeas
источник
Вам следует использовать более сфокусированный, sys.tablesа неsys.objects
marc_s
@marc_s: Спасибо, но не могли бы вы опубликовать пример? AFAIK в sys.tables, у меня нет ссылок на FK
LittleSweetSeas
3
Что я имел в виду: просто замените INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_idнаINNER JOIN sys.tables t ON t.OBJECT_ID = fc.referenced_object_id
marc_s
@LittleSweetSeas Я выполнил вышеуказанный запрос, но я не получаю имя_объекта и имя столбца для таблицы с ограничением внешнего ключа
Smart003
Вы можете усилить свой выбор, добавив немного дополнительной информации: 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_id, OBJECT_dobject_db_dbject_dbject_dbject_dobject_db_db_db_db_d_d_de_d_de_db) , COL_NAME (fc.referenced_object_id, fc.referenced_column_id) ReferencedColumn
DocOc
75

Другой способ - проверить результаты

sp_help 'TableName'

(или просто выделите указанное TableName и нажмите ALT + F1)

Со временем я просто решил уточнить свой ответ. Ниже приведен снимок экрана с результатами sp_help. A использовали базу данных AdventureWorksDW2012 для этого примера. Там много полезной информации, и то, что мы ищем, находится в самом конце - выделено зеленым:

введите описание изображения здесь

Владислав
источник
3
+1 Это дает много полезной информации, и это показывает внешние ключи внизу вывода
Hux
1
Это дает мне много информации в наименьшем количестве строк кода
Ренниш Джозеф
Это самый крутой ярлык! Полностью превосходит Ctl-R для обновления схемы!
Мистер Янг
Обновить локальный кэш InteliSense = Ctrl + Shift + R; Ctrl + R = показать / скрыть панель результатов (или, по крайней мере, это мои значения по умолчанию для SSMS2008 и SSMS2014)
Владислав
44

Попробуй это

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')
Гаятри L
источник
1
Коротко и элегантно, плюс мне подходит! Единственное, что nameвозвращаемое значение - это внутреннее имя (мне кажется), а не фактическое имя столбца в родительской таблице. Как это исправить?
Hamman Samuel
Я вижу здесь то, ParentTableNameчто всегда будет таким же, как задано ' Tablename' в предложении where (если включено). Это может быть сделано намеренно и будет более полезно при запросе более чем одной таблицы.
Ижар Аазми
28

Я нашел этот ответ довольно простым и сделал трюк для того, что мне нужно: qaru.site/questions/435 / ... / 12956348/652519

Резюме по ссылке, используйте этот запрос:

EXEC sp_fkeys 'TableName'

Быстро и просто. Мне удалось довольно быстро найти все таблицы внешних ключей, соответствующие столбцы и имена внешних ключей 15 таблиц.

Как отмечает @mdisibio ниже, вот ссылка на документацию, в которой подробно описаны различные параметры, которые можно использовать: https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp- - функциональные кнопки Transact-SQL

Майкл
источник
1
Есть пять других параметров для фильтрации, наиболее полезным из которых является второй, где вы можете указать схему, отличную от стандартной, напримерEXEC sp_fkeys 'Payroll', 'accounting'
mdisibio
8

Я использую этот сценарий, чтобы найти все подробности, связанные с внешним ключом. Я использую 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
Anvesh
источник
2
Я искал способ увидеть столбцы, которые являются внешними ключами, и связанные таблицы, на которые ссылается столбец, и это хорошо подводит итог. Спасибо!
Нейт Киндрю 08
В некоторых моих таблицах отсутствовали некоторые внешние ключи, а ответ @LittleSweetSeas показал их
Seafish
7

если вы хотите перейти через SSMS в окне обозревателя объектов, щелкните правой кнопкой мыши объект, который вы хотите удалить, и просмотрите зависимости.

Луис Л.Л.
источник
7

Вот лучший способ узнать отношения внешних ключей во всех базах данных.

exec sp_helpconstraint 'Table Name'

и еще один способ

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
источник
Это exec sp_helpconstraint 'Table Name'единственное решение, которое для меня вообще возвращает какие-либо строки. Однако название противопоказания - тарабарщина. PRIMARY KEY (clustered) PK__org_soft__3213E83FE6B07364
Тор
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
источник
1

- Следующее может дать вам больше того, что вы ищете:

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
Майк
источник
1

Вы также можете вернуть всю информацию о Foreign Keys, адаптировав ответ @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
user1
источник
1

В SQL Server Management Studio вы можете просто щелкнуть правой кнопкой мыши по таблице в проводнике объектов и выбрать «Просмотр зависимостей». Это даст вам хорошую отправную точку. Он показывает таблицы, представления и процедуры, которые ссылаются на таблицу.

Даррел Ли
источник
0

попробуйте следующий запрос.

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

это даст имя_ограничения, имена_столбцов, которые будут ссылаться, и таблицы, которые будут в зависимости от ограничения, будут там.

Smart003
источник
0

Вы можете использовать этот запрос для отображения Foreign keyограничений:

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'

Взято из http://blog.sqlauthority.com/2006/11/01/sql-server-query-to-display-foreign-key-relationships-and-name-of-the-constraint-for-each-table- в-базы данных /

user1
источник
0

Самый простой способ получить Primary Keyи Foreign Keyдля стола:

/*  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'
Ашраф Абусада
источник
0

В обозревателе объектов разверните таблицу и разверните ключи:

введите описание изображения здесь

Hank Z
источник