Я хочу изменить значение первичного ключа для одной строки в таблице, которая имеет отношения с другими таблицами:
Например,
Table Person { Id, Name, +50 fields }
Table Address { Id, City, +10 fields }
Table Person2Address { Id, PersonId, AddressId }
Я хочу изменить Человека. Идентификатор и Person2Address. PersonId
Я пробую что-то как:
BEGIN TRANSACTION
UPDATE Pers SET Id = NewId WHERE Id = OldId
UPDATE Person2Address SET PersonId = NewId WHERE PersonId = OldId
COMMIT TRANSACTION
Но конечно это обеспечивает конфликты :)
Как может я временный подавлять ограничения внешнего ключа или там лучший способ изменить идентификатор для человека?
Во-первых, изменение значения первичного ключа - плохая идея. Ваша главная задача должна состоять в том, чтобы всеми способами избегать этого.
Если вы не можете устранить необходимость обновления значения первичного ключа, то лучше всего будет определить отношения внешнего ключа между этими двумя таблицами, которые будут использоваться ON UPDATE CASCADE
, чтобы любые изменения в первичный ключ основной таблицы будет автоматически передан в дочернюю таблицу.
Для этого удалите существующее отношение внешнего ключа и затем добавьте:
ALTER TABLE dbo.Person2Address
ADD CONSTRAINT FK_Person2Address_Person
FOREIGN KEY (PersonId) REFERENCES dbo.Person(Id)
ON UPDATE CASCADE
Это должно автоматически обновить значение PersonId
таблицы Person2Address
, если Id
на человека меняется.
Теперь у вас должна быть возможность просто позвонить
UPDATE dbo.Person SET Id = NewId WHERE Id = OldId
, и это должно быть все, что есть!
Вы можете отбросить ограничения FK и воссоздать их, когда закончите.
ALTER TABLE some_table DROP CONSTRAINT my_constraint
Просмотрите эту статью для создания и изменения ограничений.
Для таких вещей проще всего использовать что-то вроде:
BEGIN TRANSACTION
UPDATE Pers SET tempId = NewId WHERE Id = OldId
UPDATE Person2Address SET tempPersonId = NewId WHERE PersonId = OldId
COMMIT TRANSACTION
Затем отбросьте поля Id и PersonId и переименуйте временные.