Підтримка складної посилальної цілісності

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

Можна сказати, що перед тим як намагатися створювати складний тригер підтримки посилальної цілісності, має сенс спробувати вирішити завдання стандартними і простішими методами Програмний код тригера підтримки посилальної цілісності міститиме серію обєднань первинних і вторинних таблиць, щоб знайти такі значення зовнішнього ключа таблиці Inserted, які не мають відповідників в первинній таблиці У розглянутому нижче прикладі таблиця ТаИеВ має зовнішній ключ, який вказує на таблицю ТааИеА Зазначу, що розглянутий програмний код не привязаний ні до якої конкретної бази даних:

CREATE TRIGGER RICheck ON Tour AFTER INSERT, UPDATE AS

SET NoCount ON IF Exists(SELECT *

FROM Inserted

LEFT OUTER JOIN BaseCamp ON InsertedBaseCampID = BaseCampBaseCampID WHERE BaseCampBaseCampID IS NULL)

BEGIN

RAISERROR

(Невідповідний зовнішній ключ: TourBaseCampID, 16, 1)

ROLLBACK TRANSACTION RETURN END

Далі ми спробуємо призначити тур Amazon Trek базового табору з ідентифікатором 99 Тригер підтримки посилальної цілісності блокує оновлення даних:

UPDATE Tour

SET BaseCampID = 99 WHERE TourID = 1

Як і очікувалося, результатом буде помилка:

Невідповідний зовнішній ключ: TourBaseCampID

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

Прикладом складної посилальної цілісності може послужити система MRP П, з якою мені доводилося працювати Ця система повинна була заповнювати рядки накладної або з рахунку-фактури, або з складської таблиці Спочатку ми намагалися вирішити завдання за допомогою двох зовнішніх ключів таблиці Allocation: один з них вказував на таблицю OrderDetail (рядки накладної) і обслуговувався вимог таблиці Product (товари) Другий ключ вказував на джерело запалення накладної і міг бути або глобальним універсальним ідентифікатором рядки (GUID) рахунки-фактури, або складським ідентифікатором GUID Оскільки другий зовнішній ключ не міг однозначно вказувати на рядок конкретної таблиці, обмеження стандартного зовнішнього ключа не здатне було впоратися із завданням

Щоб реалізувати підтримку такої складної посилальної цілісності, в таблиці Allocation був створений тригер Цей тригер перевіряв правильність ідентифікатора рядка рахунка-фактури або складської позиції Це було реалізовано за допомогою запиту відмінності, що порівнює всі рядки таблиці Inserted з полями Source ID таблиць Inventory і PurchaseOrderDetail:

CREATE TRIGGER AllocationCheck ON Allocation AFTER INSERT, UPDATE AS

SET NoCount ON

– Перевірка некоректності складської позиції IF Exists (SELECT *

FROM Inserted I LEFT OUTER JOIN Inventoryltem ON ISourcelD = InventoryltemInventoryltemID LEFT OUTER JOIN PurchaseOrderDetail ON ISourcelD = PurchaseOrderDetailPODID WHERE InventoryInventorylD IS NULL

AND PurchaseOrderDetailPODID IS NULL)

BEGIN

RAISERROR (Невірний джерело товару, 16, 1)

ROLLBACK TRANSACTION RETURN END

Як альтернативу можна було створити два зовнішніх ключа в таблиці рядків накладної (Allocation), один з яких вказував би на складську таблицю, а другий – на таблицю рахунків-фактур Це дозволило б простіше вирішити ту ж задачу Перевірка повинна була б зводитися до того, щоб тільки один з цих зовнішніх ключів містив пусте значення З такою перевіркою впоралося б таке стандартне обмеження:

ALTER TABLE Allocation

ADD CONSTRAINT AllocationSourceExclusive CHECK

(PurchaseOrderID IS NULL AND InventorylD IS NOT NULL)

OR

(PurchaseOrderID IS NOT NULL AND InventorylD IS NULL)

Вибір одного з методів підтримки складної посилальної цілісності залежить від витягання коректної інформації і звичного стилю роботи самого розробника Обидва методи вимагають використання лівих зовнішніх обєднань та функції coalesce ()

Джерело: Нільсен, Пол Microsoft SQL Server 2005 Біблія користувача : Пер з англ – М: ООО ІД Вільямс , 2008 – 1232 с : Ил – Парал тит англ

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*