2009-06-28 6 views
1

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

Система является наследственной, которую я унаследовал, и на короткий срок, пока я разрабатываю что-то более подходящее. Я хочу исправлять все, чтобы избежать сбоя передачи данных.

К сожалению, средство существует через другое приложение, чтобы создать запись в таблицу, называемую CommReceipt. Ключ называется CR_Key. если это произойдет, тогда, когда автоматическая процедура запускается для вставки, скажем, 1000 строк, которые нам нужно импортировать из другой системы (а не моей системы) с уже определенными значениями CR_Key, она терпит неудачу.

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

Это является частью плана по устранению функциональности в изгоев приложения (но это традиционная система, написанная в унаследованной unfamilar языке и может занять немного усилий)

Как справиться с первичным ключом нарушение. Могу ли я продолжить, сообщая о нарушении, с которым можно работать после запуска ввода данных.

UPDATE: Основной ключ CR_Key также является личным, существует ли способ удалить строки, которые не должны быть там, и вставлять строки с использованием того же ID. Я предполагаю .... Я отключаю личность, а затем указываю уникальные значения в «недостающих строках», это правдоподобно? мне не нужен автоматическое приращение идентификатора теперь theinsert процедура имеет идентификаторы

Благодаря

ответ

3

Вы можете использовать вместо вставки триггер. Внутри триггера выполните вставку в таблицу, где не существует CommReceipt.CR_Key = insert.CR_Key.

Create trigger T_CommReceiptInsteadOfInsert on CommReceipt 
Instead of Insert 
As 
Begin 

--Insert duplicate records into another table 
Insert Into CommReceipt_Duplicates(CR_Key, ...) 
Select CR_Key, ... 
From inserted i 
Where exists (select * from CommReceipt c Where c.CR_Key = i.CR_Key) 

--Insert non duplicate records 
Insert Into CommReceipt(CR_Key, ...) 
Select CR_Key, ... 
From inserted i 
Where not exists (select * from CommReceipt c Where c.CR_Key = i.CR_Key) 

End 
+0

спасибо, это то, что мне нужно. – Stuart

0

Нарушения ПК ограничения является серьезной ошибкой в ​​SQLServer, которые в соответствии с BOL для SQLServer 2000 является уровнем 14, так что не считается смертельным, однако это немного система проб/ошибок: уровень серьезности ошибки определяет, какой SQL-сервер будет работать с текущей транзакцией: если уровень серьезности достаточно высок, он прекратит транзакцию на уровне сервера, и вы может только перезапустить его с самого начала.

1

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

1

Во-первых, я предполагаю, что столкновения PK являются случайными и что вновь вставленные строки действительно являются независимыми объектами (в отличие от того, что должно быть лучше обработано UPDATE. Во-вторых, я предполагаю, что вы можете «Отбросьте этот первичный ключ и обработайте« ключевые »столкновения с заданием, запущенным после вставки пакета (или вообще используйте альтернативный первичный ключ).

У вас есть несколько вариантов, доступных для вас, если вы используете identity в вашем первом ключевом столбце (в этом случае ваше устаревшее приложение должно обходить личность, используя IDENTITY INSERT для успешных строк):

  • Вы можете создать новую таблицу с той же схемой, что и CommReceipt, и поместить в эту таблицу триггер INSTEAD OF, сняв первичный ключ и вставив в CommReceipt. Затем настройте устаревшее приложение для вставки в эту новую таблицу.

  • Вы можете настроить семантику идентификации в таблице CommReceipt на огромное количество вне диапазона устаревших ключей устаревших приложений. Это следует рассматривать как краткосрочное решение.

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

0

Мое предложение состояло в том, чтобы изменить процедуру внешнего импорта так, чтобы она опускала внешнюю генерируемую CR_key и просто использует тот же автогенерируемый ключ, что и все остальные.

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

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

Может быть некоторая информация внутри внешней CR_key. Это плохой дизайн ПК, но это происходит, особенно в старых системах.

Удачи.

Смежные вопросы