Решаването на проблема с променящата се таблица в Oracle SQL води до блокиране

Хей, опитвам се да създам тригер в моята база данни на Oracle, който променя всички други записи с изключение на този, който току-що е бил променен и е стартирал тригера на 0. Тъй като актуализирам записи в същата таблица като този, който е стартирал тригера Получих грешката в мутиращата таблица. За да разреша това, поставих кода като анонимна транзакция, но това причинява блокиране.

Код на задействане:

CREATE OR REPLACE TRIGGER check_thumbnail AFTER INSERT OR UPDATE OF thumbnail ON photograph
FOR EACH ROW
BEGIN
  IF :new.thumbnail = 1 THEN
    check_thumbnail_set_others(:new.url);
  END IF;
END;

Код на процедурата:

CREATE OR REPLACE PROCEDURE check_thumbnail_set_others(p_url IN VARCHAR2)
IS PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
    UPDATE photograph SET thumbnail = 0 WHERE url <> p_url;
    COMMIT;
END;

Предполагам, че причинявам задънена улица, защото тригерът се стартира в себе си. Някакви идеи?


person Mat    schedule 27.02.2011    source източник


Отговори (1)


Използването на автономна транзакция за подобни неща почти със сигурност е грешка. Какво се случва, ако транзакцията, която е вмъкнала новата миниатюра, трябва да се върне назад? Вече сте ангажирали промяната в другите редове в таблицата.

Ако искате данните да бъдат транзакционно последователни, ще ви трябват множество тригери и някакъв начин за съхраняване на състоянието. Най-простият вариант би бил да създадете пакет с колекция от thumbnail.url%type, след което да създадете три тригера в таблицата. Задействането на оператор преди ще изчисти колекцията. Тригер на ниво ред би вмъкнал стойността :new.url в колекцията. След това тригер след изявление ще прочете стойностите от колекцията и ще извика процедурата check_thumbnail_set_others (която няма да бъде автономна транзакция).

person Justin Cave    schedule 28.02.2011
comment
+1 това е стандартният метод за решаване на прословутия проблем с Мутиращата таблица. - person Jeffrey Kemp; 28.02.2011