Добро пожаловать, Гость
Логин: Пароль: Запомнить меня
SQL, PL/SQL, T-SQL: запросы, DML DDL операторы, пакеты, процедуры, функции, триггеры и последовательности.
  • Страница:
  • 1

ТЕМА: Автономные транзакции в триггере таблицы Oracle

Автономные транзакции в триггере таблицы Oracle 20 нояб 2010 21:13 #111

  • boh
  • boh аватар Автор темы
  • Посетитель
  • Посетитель
есть таблица stud - информация о студентах.
CREATE TABLE stud
    (num NUMBER(6) NOT NULL,
    fname VARCHAR2(70),
    year NUMBER(4),
    bday DATE,
    plata NUMBER(1) DEFAULT 0 CHECK(plata IN (0,1)),
    mb NUMBER(3,2),
    money NUMBER(7,2),
    adr VARCHAR2(70),
    CONSTRAINT stud_num_pk PRIMARY KEY(num),
    CONSTRAINT stud_num_ck CHECK (num>1000));

INSERT INTO stud (num, fname, year, bday, mb, money, adr) VALUES
    (535635, 'Ivanov Igor Petrovich', 1991, '21-OCT-84', 4.82, 20000, 'Karla Marksa, 12-63');
INSERT INTO stud (num, fname, year, bday, mb, money, adr) VALUES
    (535636, 'Sergeev Artyom Artyomovich', 1991, '11-JUL-84', 5.00, 20000, 'Lenina, 2-14');
INSERT INTO stud (num, fname, year, bday, mb, money, adr) VALUES
    (535637, 'Kuznetsova Tatiana Nikolaevna', 1991, '1-JAN-85', 4.00, 20000, 'Vetvistaya, 6-10');
INSERT INTO stud (num, fname, year, bday, mb, money, adr) VALUES
    (535638, 'Lebedev Artyom Fyodorovich', 1991, '07-FEB-84', 4.50, 20000, 'Frunze, 120-33');
INSERT INTO stud (num, fname, year, bday, mb, money, adr) VALUES
    (535639, 'Petrov Pyotr Petrovich', 1991, '2-JUL-84', 3.89, 20000, 'Kopteva, 5-69');
Требуется написать триггер, который при установке размера оплаты (money) для одного из студентов устанавливает ту же сумму для всех студентов в таблице. Тупой update сделать невозможно, так как в триггере нельзя производить операции над таблицей, которая запустила этот триггер.
В голову пришло два варианта:
1) Автономные транзакции
2) Использование пакета и переменных внутри пакета

Остановился на автономных транзакциях. Вариант первый, на практике просто ничего не делает
CREATE OR REPLACE TRIGGER correct_pay AFTER UPDATE OF money ON stud
	FOR EACH ROW
DECLARE
	PRAGMA AUTONOMOUS_TRANSACTION;
	first_paid NUMBER(8);
BEGIN
	SELECT num INTO first_paid FROM stud WHERE ROWNUM = 1;
	IF :new.num = first_paid THEN
		UPDATE stud SET money = :new.money WHERE num <> :new.num;
	END IF;
	COMMIT;
END correct_pay;
/


Вариант второй, для конкретного num. "Зависает" - после ручного update SQL*Plus не возвращает ничего, пока не прервёшь
CREATE OR REPLACE TRIGGER correct_pay2
AFTER UPDATE OF money ON stud 
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF (:OLD.NUM=535637) AND (:NEW.money<>:OLD.money) THEN
UPDATE stud SET money=:NEW.money WHERE (num<>535637);
COMMIT;
END IF;
END;
/
EXIT;
Чего я не понимаю?

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Re: Автономные транзакции в триггере таблицы Oracle 20 нояб 2010 21:17 #112

  • Stehh
  • Stehh аватар Автор темы
  • Посетитель
  • Посетитель
Вот решение:
create or replace trigger  correct_pay2
AFTER UPDATE OF money ON stud 
FOR EACH ROW
DECLARE
i number;
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  if :new.money <> :old.money then
    dbms_job.submit(i,'begin update stud set money='||:new.money||';end;');
  end if;
  commit;
END;

Но почему вы решили именно так реализовать задачу? Криво, имхо.. Нужно завести отдельную таблицу для оплат, и решать обычным апдейтом, а не триггерами.

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Re: Автономные транзакции в триггере таблицы Oracle 15 июль 2011 17:30 #1941

  • kiet
  • kiet аватар
  • Не в сети
  • Новый участник
  • Новый участник
  • Сообщений: 25
  • Спасибо получено: 0
кто знает почему нельзя тупо update сделать при провидение в триггере операции над таблицей, которая запустила этот триггер ?

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

Re: Автономные транзакции в триггере таблицы Oracle 12 авг 2011 08:46 #3197

после ручного update SQL*Plus не возвращает ничего, пока не прервешь, оно и не должно возвращать

Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.

  • Страница:
  • 1