Как узнать, является ли CONSTRAINT_NAME первичным или внешним ключом?
-
23-08-2019 - |
Вопрос
Использование этого SQL на SQL Server 2005
SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = @TableName
AND COLUMN_NAME=@ColumnName
Я получаю первичные ключи и внешние ключи.
Как я могу получить только внешние ключи?Как узнать, является ли ограничение первичным или внешним ключом?
Спасибо
Решение 2
Я использовал следующий SQL с SQL Server 2005, чтобы получить имена ограничений по первичному ключу:
SELECT Constraint_Name
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
WHERE UNIQUE_CONSTRAINT_NAME =
(SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = @TableName AND COLUMN_NAME = @ColumnName)
Чтобы получить имя ограничения по внешнему ключу:
SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = @TableName AND COLUMN_NAME = @ColumnName
Чтобы получить таблицу и поле внешнего ключа по имени ограничения:
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE CONSTRAINT_NAME = @ConstraintName
Чтобы получить таблицу и поле первичного ключа по имени ограничения:
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE CONSTRAINT_NAME =
(SELECT UNIQUE_CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_NAME = @ConstraintName)
Другие советы
Нашел гораздо более элегантное решение здесь
Код добавлен ниже для полноты, но вся заслуга принадлежит Пиналу Дэйву.
SELECT f.name AS ForeignKey,
OBJECT_NAME(f.parent_object_id) AS TableName,
COL_NAME(fc.parent_object_id,
fc.parent_column_id) AS ColumnName,
OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
COL_NAME(fc.referenced_object_id,
fc.referenced_column_id) AS ReferenceColumnName
FROM sys.foreign_keys AS f
LEFT JOIN sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
А если вам просто нужны первичные ключи...
SELECT i.name AS IndexName,
OBJECT_NAME(ic.OBJECT_ID) AS TableName,
COL_NAME(ic.OBJECT_ID,ic.column_id) AS ColumnName
FROM sys.indexes AS i
INNER JOIN sys.index_columns AS ic
ON i.OBJECT_ID = ic.OBJECT_ID
AND i.index_id = ic.index_id
WHERE i.is_primary_key = 1
Добавил это как дополнительный ответ, потому что он очень далек от моего предыдущего :)
Это зависит от вашей СУБД, но ограничение должно где-то содержать целевую таблицу и столбец.
Если это ограничение внешнего ключа, целевая таблица будет отличаться от текущей таблицы.Пытаться
select *
вместо
select constraint_name
чтобы увидеть все волшебные столбцы, с которыми вы можете работать.
SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = @TableName
AND COLUMN_NAME=@ColumnName
AND REFERENCED_COLUMN_NAME IS NOT NULL
Это не самое элегантное решение, но MS SQL Server использует соглашение об именовании префиксов PK и FK для ключей, поэтому вы можете использовать что-то вроде...
SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = @TableName
AND LEFT(CONSTRAINT_NAME,2) = 'FK'
Если это ваша СУБД :)
РЕДАКТИРОВАТЬ
Когда я попробовал ответ Quassnoi, я получил «неверное имя столбца» ссылка на_коломн_name '. ». ошибка.
Я использую что-то подобное.Это работает и в SQL Server 2000.
select object_name(fkx.constid) as fk_name,
fkx.keyno as num,
object_name(fkx.fkeyid) as child_table,
col_name(fkx.fkeyid, fkx.fkey) as child_column,
object_name(fkx.rkeyid) as parent_table,
col_name(fkx.rkeyid, fkx.rkey) as parent_column
from sysforeignkeys fkx
order by fk_name, fkx.keyno
Все это находится в системных таблицах и представлениях, которые довольно хорошо документированы.