Объединить первичные ключи - каскадное обновление - PullRequest
4 голосов
/ 22 октября 2008

Есть ли способ объединить два первичных ключа в один и затем каскадно обновить все затронутые отношения? Вот сценарий:

Клиенты (idCustomer int PK, Company varchar (50) и т. Д.)

CustomerContacts (idCustomerContact int PK, idCustomer int FK, Имя varchar (50) и т. Д.)

CustomerNotes (idCustomerNote int PK, idCustomer int FK, текст заметки и т. Д.)

Иногда клиенты должны быть объединены в одно. Например, у вас есть клиент с идентификатором 1, а другой с идентификатором 2. Вы хотите объединить оба, так чтобы все, что было 2, теперь было 1. Я знаю, что могу написать скрипт, который обновляет все затронутые таблицы по одному один, но я бы хотел сделать его более перспективным, используя правила каскадирования, поэтому мне не нужно обновлять сценарий каждый раз, когда добавляются новые отношения.

Есть идеи?

Ответы [ 4 ]

3 голосов
/ 22 октября 2008

Нет автоматического способа сделать это, но у вас есть пара опций, вы можете написать процедуры вручную, или вы можете либо генерировать слияние кода на регулярной основе, либо динамически генерировать его во время выполнения. Для этого вы можете использовать INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS и INFORMATION_SCHEMA.KEY_COLUMN_USAGE и INFORMATION_SCHEMA.TABLE_CONSTRAINTS и INFORMATION_SCHEMA.COLUMNS and INFORMATION_SCHEMA.TABLES для динамического построения процедуры.

Вы также можете просто обернуть всю операцию в транзакцию (хорошая идея в любом случае). Последним шагом будет удаление клиента, из которого выполняется слияние, поэтому, если в таблице, которую вы никогда не добавляли, есть RI, и вы пытаетесь выполнить слияние, произойдет сбой, поскольку вы не можете удалить клиента, с которым происходит слияние, поскольку есть зависимые записи в таблице, которые еще не были добавлены в процедуру слияния.

0 голосов
/ 13 мая 2010

Есть более новое решение для этого?

У меня такая же проблема, и на данный момент динамическое построение процедур кажется слишком сложным. Вот как это может работать в теории, но я думаю, что это не так?

В одной транзакции: 1) Временно отключите ограничение первичного ключа для клиентов 2) Обновите первичный идентификатор Cingular до «1», в котором есть каскадное правило обновления отношений, заботящееся о детях. 3) Используйте поле вторичного ключа для удаления (только) Cingular 4) Включить ограничение первичного ключа для клиентов

В будущем ожидается нечто подобное: T-SQL:

УДАЛИТЬ С ОБНОВЛЕНИЕМ idCustomer = 1 ИЗ ПОКУПАТЕЛЕЙ ГДЕ idCustomer = 2;

; -)

0 голосов
/ 22 октября 2008

Похоже, у вас будет две записи для каждой из этих таблиц, которые имеют одинаковый первичный ключ. Это твое намерение?

        <b>Customers</b>
    idCustomer Company
         1     AT&T
         2     Cingular

После слияния станет

        <b>Customers</b>
    idCustomer Company
         1     AT&T
         1     Cingular

В любом случае, наиболее надежным решением на будущее было бы написание процедуры. Вы можете пройти процедуру как для клиентов, так и она сделает всю работу по обновлению всех таблиц по мере необходимости.

0 голосов
/ 22 октября 2008

Попробуйте вместо этого использовать триггеры. При обновлении Customer (столбец idCustomer) вы вносите необходимые изменения (Delete, Update ...) в связанные таблицы.

...