Поддержка jOOQ MERGE для условной вставки PostgreSQL

Я понял, что jOOQ будет имитировать SQL MERGE в системах (таких как PostgreSQL), которые его не поддерживают.

У меня есть таблица с серийным (автоинкрементным) столбцом «id» и строковым столбцом «uri». Я хочу использовать числовые идентификаторы вместо URI в своей базе данных, поэтому я должен убедиться, что у меня есть URI в таблице поиска идентификаторов. Итак, следуя примеру в руководстве jOOQ, я подумал, что это сработает:

createDSLContext().mergeInto(tableByName("uris"))
.using(createDSLContext().selectOne())
.on(fieldByName("uri").equal("http://example.com/"))
.whenNotMatchedThenInsert(fieldByName("uri"))
.values("http://example.com/").execute();

Это дает мне DataAccessException что-то вроде:

SQL [merge into "uris" using (select 1) on "uri" = ? when not matched then insert ("uri") values (?)]; ERROR: syntax error at or near "merge"

Но затем журнал сообщает, что jOOQ продолжает работу и пытается выполнить запрос со значениями привязки. Но таблица никогда не обновляется. Итак, я предполагаю, что jOOQ не имитирует MERGE на PostgreSQL?

Затем я пробую синтаксис базы данных H2:

createDSLContext().mergeInto(tableByName("uris"), fieldByName("uri")).values(uri.toString()).execute();

Я получил:

The H2-specific MERGE syntax is not supported in dialect : POSTGRES

Какой!? Но в документации jOOQ говорится, что синтаксис H2 «может быть полностью смоделирован jOOQ для всех других баз данных, поддерживающих стандарт SQL». Конечно, PostgreSQL поддерживает стандарт SQL. Действительно ли это означает «... стандартную версию SQL для MERGE?»

Есть ли способ получить поддержку PostgreSQL для MERGE через jOOQ, или я застрял, используя те же обходные пути, которые я бы сделал в любом случае?


person Garret Wilson    schedule 11.04.2014    source источник


Ответы (2)


Чтобы убедиться, что данная функция SQL поддерживается jOOQ для вашей базы данных, ознакомьтесь с документом Javadoc @Support для соответствующего метода DSL. Это также описано в руководстве. В этом случае DSLContext.mergeInto(), где вы можете видеть, что этот оператор в настоящее время поддерживается только для этих SQLDialects :

@Support(value={CUBRID,DB2,HSQLDB,ORACLE,SQLSERVER,SYBASE})

MERGE — это очень мощный оператор, который не очень легко эмулировать, если ваша база данных изначально не поддерживает его.

«может быть полностью смоделирован jOOQ для всех других баз данных, поддерживающих стандарт SQL». Конечно, PostgreSQL поддерживает стандарт SQL. Действительно ли это означает «... стандартную версию SQL для MERGE?»

Да, конечно, должен поддерживаться стандартный оператор SQL MERGE :-) Мы уточним это в руководстве. Для этого я зарегистрировал issue #3183.

Есть ли способ получить поддержку PostgreSQL для MERGE через jOOQ, или я застрял, используя те же обходные пути, которые я бы сделал в любом случае?

К сожалению, сейчас у нас нет решения для этого в PostgreSQL. Не стесняйтесь обсуждать возможные решения в группе пользователей jOOQ.

person Lukas Eder    schedule 12.04.2014

Да, он может поддерживать, какая база данных поддерживает слияние в SQL. но postgresql не поддерживает эту функцию в стандарте SQL. См. инструкцию F312 MERGE
F313, расширенную инструкцию MERGE
F314, инструкцию MERGE с ветвью DELETE.

http://www.postgresql.org/docs/9.3/static/unsupported-features-sql-standard.html

person digoal.zhou    schedule 11.04.2014