Операції on delete і on update - просунуті можливості зовнішніх ключів - підтримка зовнішніх ключів

4.3. Операції ON DELETE і ON UPDATE

Вирази ON DELETE і ON UPDATE зовнішніх ключів використовуються для вказівки дій, які будуть виконуватися при видаленні рядків батьківської таблиці (ON DELETE) або зміні батьківського ключа (ON UPDATE). Один і той же зовнішній ключ може мати різні дії, зазначені для ON DELETE і ON UPDATE. Дії зовнішніх ключів багато в чому схожі на тригери.

У базі даних SQLite дії ON DELETE і ON UPDATE, асоційовані з зовнішнім ключем, можуть бути наступними: NO ACTION, RESTRICT, SET NULL, SET DEFAULT або CASCADE. Якщо дія не вказується спеціально, воно за замовчуванням є NO ACTION.

  • NO ACTION. опція «NO ACTION» означає, що коли батьківський ключ змінюється або видаляється з бази даних, ніяких спеціальних дій не проводиться.
  • RESTRICT. дію «RESTRICT» полягає в тому, що з додатком забороняється видаляти (для ON DELETE RESTRICT) або змінювати (для ON UPDATE RESTRICT) батьківський ключ, коли існує один або кілька посилань на нього дочірніх ключів. Різниця між ефектом від дії RESTRICT і звичайною поведінкою зовнішнього ключа полягає в тому, що дія RESTRICT запускається тоді, коли змінюється поле записи, а не тоді, коли завершується поточний запит, як у випадку негайного обмеження, і не тоді, коли завершується поточна транзакція, як в разі відкладеного обмеження. Навіть якщо зовнішній ключ був заявлений як відкладений, якщо його дією був оголошений RESTRICT, то SQLite видаватиме повідомлення про помилку негайно, як тільки віддаляється або змінюється батьківський ключ, від якого залежать дочірні ключі.
  • SET NULL. якщо дія налаштоване як «SET NULL», то при видаленні батьківського ключа (для ON DELETE SET NULL) або його зміні (для ON UPDATE SET NULL) стовпці дочірнього ключа будуть встановлюватися в значення NULL у всіх рядках дочірньої таблиці, які посилаються на удаляемую / змінну рядок батьківської таблиці.
  • SET DEFAULT. дію «SET DEFAULT» схоже на SET NULL за тим винятком, що значення кожного стовпчика дочірнього ключа встановлюється не в NULL а в значення за замовчуванням для даного стовпця. Про те, як стовпцями призначаються значення за замовчуванням, можна дізнатися в докладної документації по CREATE TABLE.
  • CASCADE. дію «CASCADE» поширює операції видалення і зміни батьківського ключа на залежні від нього дочірні ключі. Для дії ON DELETE CASCADE це виражається в тому, що кожен рядок дочірньої таблиці, яка асоційована з видаляється батьківської рядком, також буде видалена. Для дії ON UPDATE CASCADE це виражається в тому, що значення, збережені в залежному дочірньому ключі, будуть замінені на нові значення батьківського ключа.

Додамо, наприклад, вираз ON UPDATE CASCADE як показано нижче. Це - поліпшена схема з прикладу в розділі 1, що дозволяє користувачеві змінювати стовпець «artistid» (батьківський ключ зовнішнього ключа) без порушення посилальної цілісності:

Завдання дій ON UPDATE або ON DELETE не означає, що дане обмеження зовнішнього ключа не повинно задовольнятися.

Якщо, наприклад, задано дію ON DELETE SET DEFAULT, але в батьківській таблиці відсутня рядок, відповідна умолчальне значенням стовпців дочірнього ключа, то видалення батьківського ключа, для якого існують залежні дочірні ключі, призведе до порушення зовнішнього ключа. наприклад:

Схоже на ті дії SQLite, які позначені як ON DELETE SET DEFAULT і продемонстровані в прикладі вище, працює наступний тригер «AFTER DELETE»:

Всякий раз, коли видаляється рядок батьківської таблиці із зовнішнім ключем, або коли змінюються значення, збережені в шпальтах батьківського ключа, відбувається наступна логічна послідовність подій:

  1. Виконується програма тригера BEFORE.
  2. Перевіряються локальні обмеження (не зовнішнього ключа).
  3. Оновлюється або віддаляється рядок батьківської таблиці.
  4. Виконуються інші дії, необхідні зовнішнім ключем.
  5. Виконується програма тригера AFTER.

Існує одна істотна відмінність між дією ON UPDATE зовнішнього ключа і тригерами SQL. Дія ON UPDATE буде виконуватися тільки якщо значення батьківського ключа змінюються так, що нові значення батьківського ключа нееквівалентний старим. наприклад: