Лично я бы отбросил существующее ограничение и пересоздал бы его - в случае, если уже существующее ограничение каким-то образом отличается
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[MyFKName]') AND OBJECTPROPERTY(id, N'IsForeignKey') = 1)
ALTER TABLE dbo.MyTableName DROP CONSTRAINT MyFKName
GO
ALTER TABLE dbo.MyTableName ADD CONSTRAINT [MyFKName] ...
Текущий, более современный код, который я использую:
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[MyFKName]') AND parent_object_id = OBJECT_ID(N'[dbo].[MyTableName]'))
ALTER TABLE dbo.[MyTableName] DROP CONSTRAINT [MyFKName]
GO
ALTER TABLE dbo.[MyTableName] ADD CONSTRAINT [MyFKName] FOREIGN KEY ...
не уверен, есть ли какое-либо преимущество проверки sys.objects ... или sys.foreign_keys ... но в какой-то момент я выбрал sys.foreign_keys
Начиная с SQL2016, был добавлен новый синтаксис "ЕСЛИ СУЩЕСТВУЕТ", который стал намного более читабельным:
-- For SQL2016 onwards:
ALTER TABLE dbo.[MyTableName] DROP CONSTRAINT IF EXISTS [MyFKName]
GO
ALTER TABLE dbo.[MyTableName] ADD CONSTRAINT [MyFKName] FOREIGN KEY ...