Как вывести все внешние ключи, ссылающиеся на заданную таблицу в SQL Server?
Мне нужно удалить сильно связную таблицу в базе данных SQL Server. Как я могу получить список всех внешних ключей, которые нужно удалить, чтобы осуществить удаление таблицы?
(Предпочтительна помощь в виде SQL-запросов, а не действий в графическом интерфейсе управления.)
5 ответ(ов)
В данном запросе вы получаете следующую информацию:
- Само ограничение внешнего ключа (FK)
- Схему, к которой принадлежит внешний ключ
- "Таблицу-ссылающуюся" (referencing table), то есть таблица, в которой находится внешний ключ
- "Столбец-ссылающийся" (referencing column), то есть столбец в таблице-ссылающейся, который указывает на внешний ключ
- "Таблицу-ссылаемую" (referenced table), то есть таблицу, содержащую ключевой столбец, на который указывает ваш внешний ключ
- "Столбец-ссылаемый" (referenced column), то есть столбец, который является ключом, на который указывает ваш внешний ключ
Вот SQL-код, который позволяет получить эту информацию:
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
Этот запрос объединяет несколько системных представлений, чтобы извлечь необходимые данные о внешних ключах в вашей базе данных.
Я бы использовал функцию диаграмм базы данных в SQL Server Management Studio, но поскольку вы это исключили, вот что сработало для меня в SQL Server 2008 (у меня нет 2005).
Чтобы получить список имен таблиц и колонок, ссылающихся на вашу таблицу, вы можете выполнить следующий запрос:
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
Чтобы получить имена внешних ключей, используйте следующий запрос:
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')
)
Эти запросы помогут вам понять структуру внешних ключей, ссылающихся на вашу таблицу.
Попробуйте использовать следующую команду:
sp_help 'TableName'
Эта команда предоставит вам информацию о структуре таблицы, включая ее столбцы, типы данных и другую полезную информацию. Убедитесь, что заменили 'TableName'
на имя вашей таблицы.
Самый простой способ получить информацию о внешних ключах в SQL — это использовать таблицу sys.foreign_keys_columns
. Эта таблица содержит идентификаторы объектов всех внешних ключей относительно их идентификаторов колонок и таблиц. Поскольку идентификаторы остаются постоянными, результат будет надежным для дальнейших изменений в схеме и таблицах.
Вот пример запроса:
SELECT
OBJECT_NAME(fkeys.constraint_object_id) AS foreign_key_name,
OBJECT_NAME(fkeys.parent_object_id) AS referencing_table_name,
COL_NAME(fkeys.parent_object_id, fkeys.parent_column_id) AS referencing_column_name,
OBJECT_SCHEMA_NAME(fkeys.parent_object_id) AS referencing_schema_name,
OBJECT_NAME(fkeys.referenced_object_id) AS referenced_table_name,
COL_NAME(fkeys.referenced_object_id, fkeys.referenced_column_id) AS referenced_column_name,
OBJECT_SCHEMA_NAME(fkeys.referenced_object_id) AS referenced_schema_name
FROM sys.foreign_key_columns AS fkeys
Также можно добавить фильтры, используя WHERE
, например:
WHERE OBJECT_NAME(fkeys.parent_object_id) = 'table_name'
AND OBJECT_SCHEMA_NAME(fkeys.parent_object_id) = 'schema_name'
Таким образом, вы сможете получить только те внешние ключи, которые относятся к указанной таблице и схеме.
Вопрос, который вы задали, касается получения списка всех внешних ключей, ссылающихся на таблицу, которую вы хотите удалить. Данный SQL-запрос выдаёт все команды DROP FOREIGN KEY
, которые необходимы для удаления всех внешних ключей, ссылающихся на конкретную таблицу:
SELECT
'ALTER TABLE ['+sch.name+'].['+referencingTable.Name+'] DROP CONSTRAINT ['+foreignKey.name+']' AS [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'
Пример вывода:
[DropCommand]
ALTER TABLE [dbo].[OtherTable1] DROP CONSTRAINT [FK_OtherTable1_MyTable]
ALTER TABLE [dbo].[OtherTable2] DROP CONSTRAINT [FK_OtherTable2_MyTable]
Если вы хотите получить команды удаления для всех внешних ключей в текущей базе данных, просто уберите условие WHERE
.
"Вставка результатов хранимой процедуры в временную таблицу"
Как экранировать одинарную кавычку в SQL Server?
Как выполнить оператор UPDATE с JOIN в SQL Server?
Функция против Хранимой процедуры в SQL Server
Следует ли мне использовать != или <> для обозначения "не равно" в T-SQL?