jOOQ идемпотентная пакетная вставка

#java #sql #jooq

#java #sql #jooq

Вопрос:

Я пытаюсь реализовать идемпотентную вставку, этот запрос хорошо подходит для этой задачи

 insert into test_table
select *
from (
         values (1, 2, 3, 4),
                (3, 4, 5, 6),
                (1, 2, 3, 4),
                (3, 4, 5, 6)
     ) as data(a, b, c, d)
where not exists(select 1
                 from test_table
                 where test_table.a = data.a
                   and test_table.b = data.b
                   and test_table.c = data.c);
 

Пожалуйста, помогите перевести этот запрос в jOOQ DSL
Я использовал базу данных Greenplum и не поддерживал ON CONFLICT синтаксис

Ответ №1:

 ctx.insertInto(TEST_TABLE)
   .select(
       select()
       .from(values(
           row(1, 2, 3, 4),
           row(3, 4, 5, 6),
           row(1, 2, 3, 4),
           row(3, 4, 5, 6)
       ).as("data", "a", "b", "c", "d"))
       .whereNotExists(
           selectOne()
           .from(TEST_TABLE)
           .where(TEST_TABLE.A.eq(field(name("data", "a"), TEST_TABLE.A.getDataType())))
           .and(TEST_TABLE.B.eq(field(name("data", "b"), TEST_TABLE.A.getDataType())))
           .and(TEST_TABLE.C.eq(field(name("data", "c"), TEST_TABLE.A.getDataType())))
       )
   )
   .execute();
 

Этот ответ предполагает, что вы используете генератор кода для TEST_DATA (в противном случае создайте свои идентификаторы вручную, как показано выше для name("data", "a") , и т.д. или как показано здесь). Кроме того, предполагается:

 import static org.jooq.impl.DSL.*;
 

Когда Greenplum официально поддерживается, см. # 4700, тогда ON CONFLICT или ON DUPLICATE KEY IGNORE может быть эмулирован для вас.