#sqlite
Вопрос:
У меня есть таблица с целочисленными столбцами, как показано ниже. Назначение столбцов bexParentID и bexParentTypeID состоит в том, чтобы быть ограниченным внешним ключом для других строк в той же таблице, т. Е. (bexParentID,bexParentTypeID)
Иметь составное ограничение FK для (bexID,bexTypeID)
одной и той же таблицы.
Это сценарий создания:
CREATE TABLE [main].[Boolean_Expressions](
[bexID] INTEGER PRIMARY KEY NOT NULL,
[bexTypeID] INTEGER NOT NULL,
[bexParentID] INTEGER NOT NULL,
[bexParentTypeID] INTEGER NOT NULL,
FOREIGN KEY([bexParentID], [bexParentTypeID]) REFERENCES [Boolean_Expressions]([bexID], [bexTypeID]),
UNIQUE([bexID], [bexTypeID]);
Вот пример данных, которые могут появиться в этой таблице. данные
Как мне обновить тип строки (назовите ее A), в которой есть ограничения внешнего ключа из строк B, C, D…? Это нарушение-обновлять родительский тип строк B, C, D…, и это также нарушение-обновлять тип в первом.
Я могу думать только о том, чтобы «указать» B, C, D…. на другую строку, изменив их родительский идентификатор и родительский тип, чтобы указать на совершенно другую строку (назовите ее X), затем изменив тип A, затем «указав» B, C, D… обратно на A.
Ответ №1:
Добавьте ON UPDATE CASCADE
к ограничению FK:
FOREIGN KEY([bexParentID], [bexParentTypeID]) REFERENCES [Boolean_Expressions]([bexID], [bexTypeID]) ON UPDATE CASCADE
Эффект: достаточно обновить родительскую строку; все зависимые дочерние строки будут обновлены до одного и того же значения.
Комментарии:
1. Собирался предложить это, но я не могу вспомнить, как использовал составной индекс FK, поэтому не собирался предлагать без его тестирования.
2. Да, это работало с таблицей выше и другими таблицами, которые имели такое же ограничение FK для нее. Ваш ответ приведет меня к КАСКАДУ ОБНОВЛЕНИЙ, потому что раньше я не знал о предложениях FK.
Ответ №2:
Два варианта, которые могли бы быть проще.
а) Выключите внешние ключи до обновления, а затем включите их после обновления. Использование «PRAGMA foreign_keys = выключено» и «PRAGMA foreign_keys = включено»
= false
(выкл.) или= true
(вкл.) или= 0
(выкл.) или= 1
(вкл.) (любое значение, большее 0, включено)- примечание не может быть эффективно использовано (иначе это NOP) внутри транзакции.
напр.
PRAGMA foreign_keys = off;
UPDATE ....;
PRAGMA foreign_keys = on;
или
б) Используйте отложенные внешние ключи, то есть включайте:-
DEFERRABLE INITIALLY DEFERRED
В определении(определениях) внешнего ключа.
напр.
bexParentID INTEGER NOT NULL REFERENCES mytable1(bexID) DEFERRABLE INITIALLY DEFERRED
Конфликт внешних ключей проверяется при фиксации транзакции. Таким образом, изменения должны быть внесены внутри транзакции. например
BEGIN TRASNACTION;
UPDATE ....;
END TRANSACTION;
Комментарии:
1. Спасибо! отсрочка была тем, чего я добивался. Я пока не могу проголосовать, извините 🙂