Не удалось обновить более одного столбца в операторе слияния DB2i

Форум.

Я работаю с IBM System i версии 7.1.

Я столкнулся с проблемой при обновлении более чем одного столбца в операторе слияния.

Следующий оператор работает при установке одного столбца:

merge into database.table as t 
                 using ( values( 
    cast(99 as smallint) 
    ,cast('dave' as varchar(40))
                 )) 
                 as caz(
    group_id
    , group_name
    ) 
                 on t.group_id = caz.group_id 
                 when matched then update
    set t.group_name = caz.group_name
                 when not matched then 
                 insert (
    group_id
    , group_name
    ) 
                 values (
    caz.group_id
    , caz.group_name
    );

Тот же оператор больше не работает, когда я добавляю дополнительную строку набора:

merge into database.table as t 
                 using ( values( 
    cast(99 as smallint) 
    ,cast('dave' as varchar(40))
    ,cast(1 as smallint)     
                 )) 
                 as caz(
    group_id
    , group_name
    , queued_calls_above_tasa
    ) 
                 on t.group_id = caz.group_id 
                 when matched then update
    set t.group_name = caz.group_name,
    set t.queued_calls_above_tasa = caz.queued_calls_above_tasa
                 when not matched then 
                 insert (
    group_id
    , group_name
    , queued_calls_above_tasa
    ) 
                 values (
    caz.group_id
    , caz.group_name
    , caz.queued_calls_above_tasa
    );

Я получаю следующее сообщение об ошибке:

слияние с database.table как t с использованием (values(cast(99 as smallint) ,cast('dave' as varchar(40)) ,cast(1 as smallint)) as caz(
group_id , group_name , queued_calls_above_tasa )
на t.group_id = caz.group_id при совпадении затем обновить набор t.group_name = caz.group_name, установить t.queued_calls_above_tasa = caz.queued_calls_above_tasa
если не совпадает, то вставить ( group_id , group_name , queued_calls_above_tasa )
значения ( caz.group_id , caz.group_name , caz.queued_calls_above_tasa )

Состояние SQL: 42601
Код поставщика: -104
Сообщение: [SQL0104] Токен T недействителен. Действительные токены: =. Причина . . . . . : в токене T обнаружена синтаксическая ошибка. Токен T не является допустимым токеном. Частичный список допустимых токенов =. Этот список предполагает, что оператор верен с точностью до токена. Ошибка может быть раньше в операторе, но синтаксис оператора кажется действительным до этого момента. Восстановление . . . : Выполните одно или несколько из следующих действий и повторите запрос: -- Проверьте оператор SQL в области токена T. Исправьте оператор. Ошибка может быть связана с отсутствием запятой или кавычки, с ошибкой в ​​слове или с порядком предложений. -- Если токен ошибки , исправьте оператор SQL, так как он не заканчивается допустимым предложением.

Обработка завершена, так как выделенный оператор не завершился успешно

Любая помощь приветствуется.

Пожалуйста, дайте мне знать, если я могу предоставить дополнительную информацию.


person HappyCoding    schedule 12.01.2016    source источник
comment
Что вы имеете в виду под словом "больше не работает"? Вы получаете сообщение об ошибке или не получаете ожидаемого результата?   -  person Olga    schedule 12.01.2016
comment
Спасибо за это; Я отредактировал вопрос, включив в него детали сообщения об ошибке, которое я получил.   -  person HappyCoding    schedule 12.01.2016


Ответы (2)


Удаление второго «набора» позволяет ему добиться успеха следующим образом:

merge into database.table as t 
                 using ( values( 
    cast(99 as smallint) 
    ,cast('dave' as varchar(40))
    ,cast(1 as smallint)     
                 )) 
                 as caz(
    group_id
    , group_name
    , queued_calls_above_tasa
    ) 
                 on t.group_id = caz.group_id 
                 when matched then update
    set t.group_name = caz.group_name,
    t.queued_calls_above_tasa = caz.queued_calls_above_tasa
                 when not matched then 
                 insert (
    group_id
    , group_name
    , queued_calls_above_tasa
    ) 
                 values (
    caz.group_id
    , caz.group_name
    , caz.queued_calls_above_tasa
    );
person HappyCoding    schedule 12.01.2016

@HappyCoding верен, вам нужен только один оператор SET.

Другой вариант для WHEN MATCHED:

when matched then update
    set (t.group_name, t.queued_calls_above_tasa) 
          = (caz.group_name, caz.queued_calls_above_tasa )
person Charles    schedule 13.01.2016
comment
Спасибо за ваш вклад. Что касается наших ответов и лучших практик программного обеспечения, знаете ли вы, какой формат предпочтительнее другого? - person HappyCoding; 13.01.2016
comment
Альтернативный формат новее и известен как Конструктор значений строк (RVC) или Выражение значений строк. Поддержка может быть неполной, если вы пытаетесь написать код, использующий несколько баз данных. - person Charles; 13.01.2016
comment
Спасибо за информацию, @Charles. Я также нашел следующую статью в качестве хорошей ссылки: sqlmag.com/sql-server/row -значение-конструктор - person HappyCoding; 13.01.2016
comment
@HappyCoding... обратите внимание, что этот сайт обслуживает MS SQL Server, а не DB2. Хотя в данном конкретном случае статья больше применима к DB2, поскольку MS SQL Server не поддерживает RVC. - person Charles; 14.01.2016