Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Можно ли определить операцию (insert or update) которую сделал MERGE?  [new]
PL/SQL
Member

Откуда:
Сообщений: 92
Возможно ли использование RETURNING с MERGE?
17 июл 09, 14:49    [7429560]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли определить операцию (insert or update) которую сделал MERGE?  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116325
PL/SQL
Возможно ли использование RETURNING с MERGE?


Оригинально.
Вопрос в заголовке темы - да
Вопрос в самой теме - нет
17 июл 09, 14:52    [7429591]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли определить операцию (insert or update) которую сделал MERGE?  [new]
PL/SQL
Member

Откуда:
Сообщений: 92
Спасибо. Тогда merge не пройдет. Просветите еще по поводу первого вопроса, как это сделать?
17 июл 09, 14:56    [7429620]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли определить операцию (insert or update) которую сделал MERGE?  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116325
PL/SQL
Спасибо. Тогда merge не пройдет. Просветите еще по поводу первого вопроса, как это сделать?


Посадить триггеры на инсерт и апдейт на соответствующую таблицу
с логированием. MERGE- то своих "родных" триггеров не имеет...
17 июл 09, 14:58    [7429643]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли определить операцию (insert or update) которую сделал MERGE?  [new]
Lecter
Member

Откуда: Киев
Сообщений: 2032
dmidek

Посадить триггеры на инсерт и апдейт на соответствующую таблицу
с логированием. MERGE- то своих "родных" триггеров не имеет...


Может проще разделить на две операции? Одна вставка другая обновление. И число строк можна получить как для 1й операции так и для 2й в независимости. Да и ретурнинг можна юзать.
17 июл 09, 15:01    [7429663]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли определить операцию (insert or update) которую сделал MERGE?  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116325
Lecter
dmidek

Посадить триггеры на инсерт и апдейт на соответствующую таблицу
с логированием. MERGE- то своих "родных" триггеров не имеет...


Может проще разделить на две операции? Одна вставка другая обновление. И число строк можна получить как для 1й операции так и для 2й в независимости. Да и ретурнинг можна юзать.


Если мерджи зажигают, значит это кому- нибудь нужно

Просто нужно решить, так ли важна возможность RETURNING-a, чтобы из за нее
отказываться от функционала.

С другой стороны, где то на форуме andrey_anonaymous показывал эмуляцию
RETURING в MERGE через пакетные переменные в триггерах

С третьей стороны, триггеры в MERGE страшно багоопасны.

В общем есть повод для раздумий, может конкретная проблема автора
поможет принять оптимальное решение...
17 июл 09, 15:08    [7429715]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли определить операцию (insert or update) которую сделал MERGE?  [new]
PL/SQL
Member

Откуда:
Сообщений: 92
Всем спасибо. Returning необходим, придется делать через insert и update.
17 июл 09, 15:34    [7429896]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли определить операцию (insert or update) которую сделал MERGE?  [new]
Lecter
Member

Откуда: Киев
Сообщений: 2032
PL/SQL
Всем спасибо. Returning необходим, придется делать через insert и update.


Кстати на правах оффтопа. Можно запихнуть их в процедуру( функцию в зависимости от логики ) и пользоваться "эмуляцией" мержа.
17 июл 09, 15:37    [7429916]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли определить операцию (insert or update) которую сделал MERGE?  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116325
Lecter
PL/SQL
Всем спасибо. Returning необходим, придется делать через insert и update.


Кстати на правах оффтопа. Можно запихнуть их в процедуру( функцию в зависимости от логики ) и пользоваться "эмуляцией" мержа.


На правах второго оффтопа к автору.
Только делайте сначала UPDATE и по SQL%ROWCOUNT= 0 INSERT,
и ни в коем случае не наоборот с UPDATE по INSERT-овскому исключению ORA-00001.
Оракл теряет огромное количество времени , ища в словарях, а что там
за констрейнт нарушился...
17 июл 09, 15:43    [7429952]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли определить операцию (insert or update) которую сделал MERGE?  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
(На правах совсем бредового офтопа )

всегда делать инсерт с log errors .. unlimited (10gR2+) ну а те строки, кто в лог приедет
с ошибкой про дупликейт разворачивать на апдейт
(но не хаметь - в инсерт-триггере над логотаблой - не стОит ;).

при всём накладе, если соотношение строк upd << ins оно мож. и не полный бред.
17 июл 09, 17:17    [7430613]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли определить операцию (insert or update) которую сделал MERGE?  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
dmidek
Вопрос в самой теме - нет


But can be mimicked (except DELETE WHERE):

SQL> DROP TABLE EMP1
  2  /

Table dropped.

SQL> DROP PACKAGE PKG1
  2  /

Package dropped.

SQL> DROP TYPE T_EMP_NO_TBL
  2  /

Type dropped.

SQL> DROP TYPE T_EMP_NO_OBJ
  2  /

Type dropped.

SQL> CREATE OR REPLACE
  2     TYPE T_EMP_NO_OBJ
  3       AS OBJECT(
  4                 EMP_NO NUMBER,
  5                 ACTION VARCHAR2(10)
  6                );
  7  /

Type created.

SQL> CREATE OR REPLACE
  2     TYPE T_EMP_NO_TBL
  3       AS TABLE OF T_EMP_NO_OBJ;
  4  /

Type created.

SQL> CREATE OR REPLACE
  2    PACKAGE PKG1
  3      IS
  4        EMP_NO_TBL T_EMP_NO_TBL := T_EMP_NO_TBL();
  5  END;
  6  /

Package created.

SQL> CREATE TABLE EMP1
  2    AS
  3      SELECT  EMPNO,
  4              ENAME,
  5              SAL
  6        FROM  EMP
  7        WHERE DEPTNO = 10
  8  /

Table created.

SQL> CREATE OR REPLACE
  2    TRIGGER EMP1_BIUS
  3    BEFORE INSERT
  4        OR UPDATE
  5    ON EMP1
  6    BEGIN
  7        PKG1.EMP_NO_TBL.DELETE;
  8  END;
  9  /

Trigger created.

SQL> CREATE OR REPLACE
  2    TRIGGER EMP1_BIUR
  3    BEFORE INSERT
  4        OR UPDATE
  5    ON EMP1
  6    FOR EACH ROW
  7    BEGIN
  8        PKG1.EMP_NO_TBL.EXTEND;
  9        IF INSERTING
 10          THEN
 11            PKG1.EMP_NO_TBL(PKG1.EMP_NO_TBL.COUNT) := T_EMP_NO_OBJ(:NEW.EMPNO,'INSERT');
 12          ELSE
 13            PKG1.EMP_NO_TBL(PKG1.EMP_NO_TBL.COUNT) := T_EMP_NO_OBJ(:NEW.EMPNO,'UPDATE');
 14        END IF;
 15  END;
 16  /

Trigger created.

SQL> MERGE
  2    INTO  EMP1 E1
  3    USING EMP E
  4    ON (E1.EMPNO = E.EMPNO)
  5    WHEN MATCHED THEN UPDATE SET E1.SAL = E.SAL
  6    WHEN NOT MATCHED THEN INSERT VALUES(E.EMPNO,E.ENAME,E.SAL)
  7  /

14 rows merged.

SQL> BEGIN
  2      FOR I IN 1..PKG1.EMP_NO_TBL.COUNT LOOP
  3        DBMS_OUTPUT.PUT_LINE(PKG1.EMP_NO_TBL(I).EMP_NO || ' - ' || PKG1.EMP_NO_TBL(I).ACTION);
  4      END LOOP;
  5  END;
  6  /
7782 - UPDATE
7839 - UPDATE
7934 - UPDATE
7844 - INSERT
7521 - INSERT
7654 - INSERT
7788 - INSERT
7698 - INSERT
7566 - INSERT
7499 - INSERT
7902 - INSERT
7369 - INSERT
7876 - INSERT
7900 - INSERT

PL/SQL procedure successfully completed.

SQL>  

SY.

Сообщение было отредактировано: 17 июл 09, 18:34
17 июл 09, 18:30    [7431094]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли определить операцию (insert or update) которую сделал MERGE?  [new]
wildwind
Member

Откуда: Москва
Сообщений: 1296
orawish,

Продолжая бред и оффтоп,
по первому вопросу
merge ... 
update set dst.c1 = f1(src.c1) ...
insert ... values ( f2(src.c1) ...
а в f1, f2 много чего придумать можно :)

При определенных условиях и для второго вопроса сгодится.
18 июл 09, 04:07    [7431958]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить