Скопировать ограничения FOREIGN KEY из одной базы данных в другую
У меня есть локальный db, который имеет ограничения FOREIGN KEY.
Живая версия этой базы данных веб-сайтов не содержит никаких ограничений FOREIGN KEY.
Как я могу "копировать/вставлять", импортировать/экспортировать ТОЛЬКО ограничения FOREIGN KEY от одного db к другому?
Я НЕ хочу копировать любые данные, только ограничения.
Спасибо
Ответы
Ответ 1
Вы можете использовать этот script, который я нашел в http://www.siusic.com/wphchen/how-to-script-out-all-the-foreign-keys-of-a-table-106.html. Замените tablename1 и tablename2 на список таблиц, для которых вы хотите получить внешние ключи.
select 'ALTER TABLE '+object_name(a.parent_object_id)+
' ADD CONSTRAINT '+ a.name +
' FOREIGN KEY (' + c.name + ') REFERENCES ' +
object_name(b.referenced_object_id) +
' (' + d.name + ')'
from sys.foreign_keys a
join sys.foreign_key_columns b
on a.object_id=b.constraint_object_id
join sys.columns c
on b.parent_column_id = c.column_id
and a.parent_object_id=c.object_id
join sys.columns d
on b.referenced_column_id = d.column_id
and a.referenced_object_id = d.object_id
where object_name(b.referenced_object_id) in
('tablename1','tablename2')
order by c.name
Ответ 2
Мне нужно было сделать что-то подобное, где мне нужно было использовать одни и те же внешние ключи на нескольких серверах, за исключением того, что некоторые из них уже были добавлены. Поэтому я добавил проверку "ЕСЛИ НЕ СУЩЕСТВУЕТ" в начало операторов создания:
SELECT N'
IF NOT EXISTS (SELECT * FROM sys.foreign_keys
WHERE object_id = OBJECT_ID(''' + QUOTENAME(fk.name) + ''')
AND parent_object_id = OBJECT_ID(''' + QUOTENAME(cs.name) + '.' + QUOTENAME(ct.name) +''')
)
BEGIN
ALTER TABLE '
+ QUOTENAME(cs.name) + '.' + QUOTENAME(ct.name)
+ ' ADD CONSTRAINT ' + QUOTENAME(fk.name)
+ ' FOREIGN KEY (' + STUFF((SELECT ',' + QUOTENAME(c.name)
-- get all the columns in the constraint table
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fkc
ON fkc.parent_column_id = c.column_id
AND fkc.parent_object_id = c.[object_id]
WHERE fkc.constraint_object_id = fk.[object_id]
ORDER BY fkc.constraint_column_id
FOR XML PATH(N''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 1, N'')
+ ') REFERENCES ' + QUOTENAME(rs.name) + '.' + QUOTENAME(rt.name)
+ '(' + STUFF((SELECT ',' + QUOTENAME(c.name)
-- get all the referenced columns
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fkc
ON fkc.referenced_column_id = c.column_id
AND fkc.referenced_object_id = c.[object_id]
WHERE fkc.constraint_object_id = fk.[object_id]
ORDER BY fkc.constraint_column_id
FOR XML PATH(N''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 1, N'') + ')
END'
FROM sys.foreign_keys AS fk
INNER JOIN sys.tables AS rt -- referenced table
ON fk.referenced_object_id = rt.[object_id]
INNER JOIN sys.schemas AS rs
ON rt.[schema_id] = rs.[schema_id]
INNER JOIN sys.tables AS ct -- constraint table
ON fk.parent_object_id = ct.[object_id]
INNER JOIN sys.schemas AS cs
ON ct.[schema_id] = cs.[schema_id]
WHERE rt.is_ms_shipped = 0 AND ct.is_ms_shipped = 0;
Если вы не хотите, чтобы проверки "ЕСЛИ НЕ СУЩЕСТВУЮТ" (они действительно не должны иметь значения), просто удалите 5 верхних строк и добавьте "SELECT N" непосредственно перед "НАЧАТЬ", например:
SELECT N'BEGIN
ALTER TABLE '
+ QUOTENAME(cs.name) + '.' + QUOTENAME(ct.name)
- где-то в Интернете я нашел ядро этого запроса и некоторое время его модифицировал. Благодарим их за то, что они собрали большую часть этого...