Цель: Обмен первичными ключами двух записей без столкновения с ORA-00001: нарушено уникальное ограничение. Решение, которое «работает» (далее), является просто глупым взломом. Есть ли функция/метод, чтобы отложить принудительное принуждение до совершения транзакции?
Насколько мотивации - унаследованное приложение, которое использует эти данные имеют недостаток дизайна и опирается на порядке идентификаторов и значениях - запрос должен поменять значения PK следующим образом:Лучший способ обмена двумя значениями первичного ключа и обход ORA-00001: уникальное ограничение нарушено?
BEFORE:
388 English
389 French
AFTER:
389 English
388 French
Что Безразлично «т Работа:
BEGIN
UPDATE SPOKEN_LANGUAGES
SET id = 388
WHERE id = 389;
UPDATE SPOKEN_LANGUAGES
SET id = 389
WHERE id = 388;
END;
Hack/решение, что 'работает'
DECLARE
V_MAGIC_NUMBER NUMBER := 9999999;
BEGIN
UPDATE SPOKEN_LANGUAGES
SET id = 388 + V_MAGIC_NUMBER
WHERE id = 389;
UPDATE SPOKEN_LANGUAGES
SET id = 389 + V_MAGIC_NUMBER
WHERE id = 388;
UPDATE SPOKEN_LANGUAGES
SET id = id - V_MAGIC_NUMBER
WHERE id = 389 + V_MAGIC_NUMBER;
UPDATE SPOKEN_LANGUAGES
SET id = id - V_MAGIC_NUMBER
WHERE id = 388 + V_MAGIC_NUMBER;
END;
Таблица Определение:
CREATE TABLE SPOKEN_LANGUAGES
(
ID NUMBER(10) NOT NULL,
LANGUAGE_NAME VARCHAR2(40 BYTE) NOT NULL
)
PK/UNIQUE INDEX:
CREATE UNIQUE INDEX SL_PK ON SPOKEN_LANGUAGES (ID)
насчет просто сбросив индекс, выполняющий обновление, а затем перестраивающий индекс? – BobC
@BobC Это было определенно предложение, которое появилось - казалось, разработчики приложений неохотно приняли эту стратегию. Я также предложил реорганизовать схему и/или приложение для поддержки того, что они пытаются выполнить; а не пытаться «исправить», как есть. –
Это одноразовое решение или какое-то регулярное обслуживание? Если это был один, я не вижу большой проблемы с откатом и перестройкой индекса. Сказав это, @a_hourse придумал правильный ответ. Но, как вы говорите, и приложение полагается на этот заказ, скорее всего, столкнется с другими проблемами позже ... – BobC