При установке слияния DB2 возникает ошибка "Строка не найдена для MERGE"

Я пытаюсь выполнить базовое обновление на iSeries db2 с помощью оператора MERGE, как описано в Есть ли в DB2 оператор вставки или обновления? и http://db2performance.blogspot.com/2011/12/merge-make-your-upserts-quick.html. При выполнении он дает мне Row not found for MERGE. SQLSTATE=02000 вместо вставки строки. Поскольку у меня в операторе when not matched then insert, почему он возвращает ошибку вместо вставки? Я осмотрел все ТАК и не увидел этой конкретной проблемы.

Вот утверждение, которое я использую:

merge into UFDFTRN as T using (
    select * from UFDFTRN 
    where DFCNO = 354 and DFINV = 1179 and DFLC = 1 and DFDATE = '2017-01-31'
        and DFSPLT = 0 and DFSEQ = 100
) as S on (
    T.DFCNO = S.DFCNO and T.DFINV = S.DFINV and T.DFDATE = S.DFDATE and
    T.DFSPLT = S.DFSPLT and T.DFSEQ = S.DFSEQ
) when matched then 
    update set DFSEQ = 1000, DFTRAN = 0, DFITEM = 'F224', DFRITM = '0', 
        DFDESC = 'DAIRY VTM PREMIX', DFQTY = 3, DFUM = '',DESIQU = 0, DFRTQU = 3,
        DFUPR = 0, DFCTUP = 0, DFUCST = 0, DFOUCST = 0, DFAMT = 0, DFOAMT = 0, DFCODE = '',
        DFURAT = '', DFCGCD = '0', DFCTNO = 0, DFADJITM = '', DFADJPCT = 0, DFMNFITM = '',
        DFMNFRAT = '', DFMNFQTY = '0', DFMNFTQTY = '0'
when not matched then 
    insert (DFCNO, DFINV, DFLC, DFDATE, DFSPLT, DFSEQ, DFTRAN, DFITEM, DFRITM, DFDESC,
        DFQTY, DFUM, DFSIQU, DFRTQU, DFUPR, DFCTUP, DFUCST, DFOUCST, DFAMT, DFOAMT, DFCODE,
        DFURAT, DFCGCD, DFCTNO, DFADJITM, DFADJPCT, DFMNFITM, DFMNFRAT, DFMNFQTY, DFMNFTQTY
    ) values (
        354, 1179, 1, '2017-01-31', 0, 1000, 0, 'F224', '0', 'DAIRY VTM PREMIX', 3, '', 0,
        3, 0, 0, 0, 0, 0, 0, '', '', '0', 0, '', 0, '', '', '0', '0'
    )

person Kelly Keller-Heikkila    schedule 31.01.2017    source источник
comment
Ваше утверждение не имеет для меня никакого смысла ... Исходный и целевой файлы совпадают; это не то, как вы обычно используете слияние. Кроме того, я никогда не видел слияния с жестко запрограммированными значениями во вставке и обновлении. Чего вы пытаетесь достичь?   -  person Charles    schedule 31.01.2017
comment
Извините за путаницу. У меня есть ряд данных, которые я хочу обновить. Если строка еще не существует, я хочу создать новую строку. По сути, я хочу сделать апсерт, аналогичный тому, как это можно сделать в MySQL с on duplicate key update. Ссылки, которые я разместил, подразумевают, что upsert можно выполнить с помощью слияния. Есть ли другой / лучший способ? Я использую одну и ту же таблицу, потому что на самом деле я не объединяю две разные таблицы, а просто пытаюсь проверить, существует ли запись, и если да, обновить ее, а если нет, вставить ее.   -  person Kelly Keller-Heikkila    schedule 31.01.2017
comment
Вы просто пытаетесь обновить 1 запись, 1 раз с заданным набором значений? Или набор записей с неизвестным набором значений?   -  person Charles    schedule 31.01.2017
comment
Обновите 1 запись 1 раз с заданным набором значений.   -  person Kelly Keller-Heikkila    schedule 31.01.2017


Ответы (2)


Вероятно, это должно выглядеть примерно так:

merge into UFDFTRN as T using (
    select 354 DFCNO, 1179 DFINV, 1 DFLC, '2017-01-31' DFDATE, 0 DFSPLT, 100 DFSEQ
           , 'DAIRY VTM PREMIX' f1 -- all other columns you might need
    from sysibm.sysdummy1 
) as S 
on (
    T.DFCNO = S.DFCNO and T.DFINV = S.DFINV and T.DFDATE = S.DFDATE and
    T.DFSPLT = S.DFSPLT and T.DFSEQ = S.DFSEQ
) 
when matched then 
    update set T.DFSEQ = S.DFSEQ, T.DFTRAN = S.DFTRAN, -- etc. etc.
when not matched then 
    insert (DFCNO, DFINV, ... -- etc. etc.
    ) values (
        S.DFSNO, S.DFINV, ..., S.F1, ...-- etc. etc.
    )

PS. Не испытано.

person mustaccio    schedule 31.01.2017

У Мустаччо правильный формат для слияния ...

Но, как я уже сказал, это действительно забавный способ использования слияния.

Лично для одного раза я бы просто

update UFDFTRN 
set (DFCNO, DFINV, DFLC, DFDATE, DFSPLT, DFSEQ, DFTRAN, DFITEM, DFRITM, DFDESC,
        DFQTY, DFUM, DFSIQU, DFRTQU, DFUPR, DFCTUP, DFUCST, DFOUCST, DFAMT, DFOAMT, DFCODE,
        DFURAT, DFCGCD, DFCTNO, DFADJITM, DFADJPCT, DFMNFITM, DFMNFRAT, DFMNFQTY, DFMNFTQTY
    ) = (
        354, 1179, 1, '2017-01-31', 0, 1000, 0, 'F224', '0', 'DAIRY VTM PREMIX', 3, '', 0,
        3, 0, 0, 0, 0, 0, 0, '', '', '0', 0, '', 0, '', '', '0', '0'
    )
where DFCNO = 354 and DFINV = 1179 and DFLC = 1 and DFDATE = '2017-01-31'
        and DFSPLT = 0 and DFSEQ = 100

И если это не удалось, и запись не найдена, просто измените обновление на вставку

insert into UFDFTRN 
 (DFCNO, DFINV, DFLC, DFDATE, DFSPLT, DFSEQ, DFTRAN, DFITEM, DFRITM, DFDESC,
        DFQTY, DFUM, DFSIQU, DFRTQU, DFUPR, DFCTUP, DFUCST, DFOUCST, DFAMT, DFOAMT, DFCODE,
        DFURAT, DFCGCD, DFCTNO, DFADJITM, DFADJPCT, DFMNFITM, DFMNFRAT, DFMNFQTY, DFMNFTQTY
    ) values (
        354, 1179, 1, '2017-01-31', 0, 1000, 0, 'F224', '0', 'DAIRY VTM PREMIX', 3, '', 0,
        3, 0, 0, 0, 0, 0, 0, '', '', '0', 0, '', 0, '', '', '0', '0'
    )
person Charles    schedule 31.01.2017
comment
Это не очень жестко запрограммировано в моем коде. Я выполняю запрос только один раз для каждого выполнения кода, но жестко запрограммированные значения на самом деле являются переменными в PHP, но отправленный мной запрос - это то, что было фактически отправлено в DB2. Я хотел выполнить слияние, а не два запроса, потому что я хочу убедиться, что не будет проблем с параллелизмом, если один и тот же запрос будет выполняться двумя или более потоками одновременно. - person Kelly Keller-Heikkila; 01.02.2017