Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Merge + Insert + Update  [new]
Testor1
Member

Откуда:
Сообщений: 679
Всем привет!

Есть проблема с Merge в триггере на insert, update, delete

MERGE tbl_dst  dst
using (select col1, col2, sum_bal from  inserted) src
ON  dst.col1=src.col1 AND dst.col2 = src.col2
WHEN  NOT MATCHED THEN INSERT(col1,col2,sum_bal)  VALUES(src.col1, src.col2, src.sum_bal)
WHEN MATCHED UPDATE SET dst.sum_bal = dst.sum_bal + src.sum_bal


В случае если в inserted появляется повторяющаяся комбинация col1, col2, то получаю сообщение об ошибке

The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.


Как переделать merge, чтобы сохранить логику обновления?
29 окт 12, 23:48    [13393999]     Ответить | Цитировать Сообщить модератору
 Re: Merge + Insert + Update  [new]
dalex1973
Member

Откуда: Польша
Сообщений: 287
А если сгруппировать?

MERGE tbl_dst  dst
using (select col1, col2, SUM(sum_bal) sum_bal from  inserted
GROUP BY col1,col2
) src
ON  dst.col1=src.col1 AND dst.col2 = src.col2
WHEN  NOT MATCHED THEN INSERT(col1,col2,sum_bal)  VALUES(src.col1, src.col2, src.sum_bal)
WHEN MATCHED UPDATE SET dst.sum_bal = dst.sum_bal + src.sum_bal
29 окт 12, 23:57    [13394007]     Ответить | Цитировать Сообщить модератору
 Re: Merge + Insert + Update  [new]
invm
Member

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

А вот с чего вы решили, что данные будут агрегироваться? Такого никто не обещал.
MERGE tbl_dst  dst
using (select col1, col2, sum(sum_bal) as sum_bal from  inserted group by col1, col2) src
ON  dst.col1=src.col1 AND dst.col2 = src.col2
WHEN  NOT MATCHED THEN INSERT(col1,col2,sum_bal)  VALUES(src.col1, src.col2, src.sum_bal)
WHEN MATCHED UPDATE SET dst.sum_bal = dst.sum_bal + src.sum_bal
30 окт 12, 00:01    [13394015]     Ответить | Цитировать Сообщить модератору
 Re: Merge + Insert + Update  [new]
Testor1
Member

Откуда:
Сообщений: 679
dalex1973
А если сгруппировать?

MERGE tbl_dst  dst
using (select col1, col2, SUM(sum_bal) sum_bal from  inserted
GROUP BY col1,col2
) src
ON  dst.col1=src.col1 AND dst.col2 = src.col2
WHEN  NOT MATCHED THEN INSERT(col1,col2,sum_bal)  VALUES(src.col1, src.col2, src.sum_bal)
WHEN MATCHED UPDATE SET dst.sum_bal = dst.sum_bal + src.sum_bal


Группировка работает, но я хотел бы без группировки.
Делаю логирование изменений и хотел бы видеть какая транзакция и на какую сумму измененяла конечный баланс.
30 окт 12, 00:06    [13394022]     Ответить | Цитировать Сообщить модератору
 Re: Merge + Insert + Update  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
Testor1
Группировка работает, но я хотел бы без группировки.
Делаю логирование изменений и хотел бы видеть какая транзакция и на какую сумму измененяла конечный баланс.
Без группировки не выйдет. А все необходимое для логирования есть в inserted.
30 окт 12, 00:19    [13394050]     Ответить | Цитировать Сообщить модератору
 Re: Merge + Insert + Update  [new]
aleks2
Guest
Testor1
dalex1973
А если сгруппировать?

MERGE tbl_dst  dst
using (select col1, col2, SUM(sum_bal) sum_bal from  inserted
GROUP BY col1,col2
) src
ON  dst.col1=src.col1 AND dst.col2 = src.col2
WHEN  NOT MATCHED THEN INSERT(col1,col2,sum_bal)  VALUES(src.col1, src.col2, src.sum_bal)
WHEN MATCHED UPDATE SET dst.sum_bal = dst.sum_bal + src.sum_bal


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


Если у вас dst.col1=src.col1 AND dst.col2 = src.col2, то как же вы их различите, эти транзакции?
Фигню несете...
30 окт 12, 05:23    [13394250]     Ответить | Цитировать Сообщить модератору
 Re: Merge + Insert + Update  [new]
kain111
Member

Откуда:
Сообщений: 226
автор
Делаю логирование изменений и хотел бы видеть какая транзакция и на какую сумму измененяла конечный баланс.

что у вас за логирование с операцией Merge ? добавьте дату.
или вы храните только последний шаг ? тогда используйте группировку
30 окт 12, 09:05    [13394596]     Ответить | Цитировать Сообщить модератору
 Re: Merge + Insert + Update  [new]
Testor1
Member

Откуда:
Сообщений: 679
kain111
автор
Делаю логирование изменений и хотел бы видеть какая транзакция и на какую сумму измененяла конечный баланс.

что у вас за логирование с операцией Merge ? добавьте дату.
или вы храните только последний шаг ? тогда используйте группировку


Да скорее всего только группировка и подходит.


При обновлении (Insert/Update/Delete) таблицы детализации (table_details), я обновляю значение баланса каждого клиента в агрегированной таблице (table_balances). Все реализовано на уровне триггеров, а также логирование изменений в таблицах.

Для моей задачи merge очень подходит.
30 окт 12, 09:22    [13394649]     Ответить | Цитировать Сообщить модератору
 Re: Merge + Insert + Update  [new]
kain111
Member

Откуда:
Сообщений: 226
можно попробывать использовать опцию merge
автор
<output_clause>

Возвращает строку для каждой строки в target_table, которая обновляется, вставляется или удаляется без определенного порядка. Дополнительные сведения об аргументах этого предложения см. в разделе Предложение OUTPUT (Transact-SQL).

OUTPUT deleted.*, $action, inserted.* INTO #MyTempTable;


вставляя во временную таблицу все измененные записи и запустить цикл сколько будет максимальных повторений в котором бы вызывалась merge с внешним соединением к нашей временной таблице.
те.
1)тригер срабатывает, из inserted получется максимальное полличество повторений и столько раз выполняется цикл.
2) происходит merge с опцией DISTINCT соединяя с нашей пустой таблице
3) все изменения попадают с опции OUTPUT в нашу временную таблицу
4) повторный вызов merge с соединением нашей таблице. которое отсеет уже обработанные данные.
30 окт 12, 13:51    [13396600]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить