我已经明白jOOQ会在不支持它的系统(例如PostgreSQL)上模拟SQL MERGE。
我有一个带有序列(自动增量)" id"列和字符串" uri"柱。我想在我的数据库中使用数字ID而不是URI,所以我必须确保在ID查找表中有一个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在PostgreSQL上没有模拟MERGE?
然后我尝试使用H2数据库语法:
createDSLContext().mergeInto(tableByName("uris"), fieldByName("uri")).values(uri.toString()).execute();
我明白了:
The H2-specific MERGE syntax is not supported in dialect : POSTGRES
什么!但jOOQ documentation表示,对于支持SQL标准的所有其他数据库,jOOQ可以完全模拟H2语法""当然PostgreSQL支持SQL标准。它真的意味着......#MERGE的SQL标准版本?"
有没有办法通过jOOQ获得对MERGE的PostgreSQL支持,或者我仍然坚持做同样的解决方法?
答案 0 :(得分:1)
为了确保jOOQ为您的数据库支持给定的SQL功能,请考虑相关DSL方法上的Javadoc @Support
注释。 This is also documented in the manual。在这种情况下,DSLContext.mergeInto()
,您可以看到此语句目前仅支持这些SQLDialects
:
@Support(value={CUBRID,DB2,HSQLDB,ORACLE,SQLSERVER,SYBASE})
MERGE
是一个非常强大的语句,如果您的数据库本身不支持它,那么它就不容易模拟。
对于支持SQL标准的所有其他数据库,"可以由jOOQ完全模拟。"当然PostgreSQL支持SQL标准。它真的意味着......#MERGE的SQL标准版本?"
是的,当然,必须支持SQL标准MERGE
声明:-)我们将在手册中澄清这一点。我已为此注册了issue #3183。
有没有办法通过jOOQ获得对MERGE的PostgreSQL支持,或者我仍然坚持做同样的解决方法?
目前,遗憾的是,我们在PostgreSQL中没有这方面的解决方案。欢迎在jOOQ User Group上讨论可能的解决方案。
答案 1 :(得分:0)
是的,它可以支持哪个数据库支持SQL中的合并。
但是postgresql不支持SQL标准中的这个功能。
请参阅
F312 MERGE声明
F313增强型MERGE声明
带有DELETE分支的F314 MERGE语句
http://www.postgresql.org/docs/9.3/static/unsupported-features-sql-standard.html