1 回答

TA貢獻1797條經驗 獲得超6個贊
從 jOOQ 3.14.0 開始
該JSON_OBJECTAGG
聚合函數是在本機現在jOOQ支持:
DSL.jsonObjectAgg(TABLE.NAME, TABLE.VALUE).filterWhere(TABLE.NAME.isNotNull());
FILTER
在 jOOQ 3.14.8 中添加了對子句的支持。
從 jOOQ 3.14.8 和 3.15.0 開始
如果 jOOQ 沒有實現特定的聚合函數,您現在可以指定DSL.aggregate()
使用自定義聚合函數。
DSL.aggregate("json_object_agg", SQLDataType.JSON, TABLE.NAME, TABLE.VALUE) .filterWhere(TABLE.NAME.isNotNull());
這是通過https://github.com/jOOQ/jOOQ/issues/1729實現的
對于 jOOQ 3.14.0
jOOQ DSL
API 中缺少一個功能,即創建純 SQL 聚合函數。這還不可用的原因(從 jOOQ 3.11 開始)是因為有很多微妙的內部結構來指定支持所有供應商特定選項的供應商不可知聚合函數,包括:
FILTER (WHERE ...)
條款(如您在問題中提到的),必須使用CASE
OVER (...)
子句將聚合函數轉換為窗口函數WITHIN GROUP (ORDER BY ...)
支持有序集合聚合函數的子句DISTINCT
條款,如果支持其他特定于供應商的聚合函數擴展
在您的特定情況下,簡單的解決方法是一直使用純 SQL 模板,正如您在問題中提到的:
DSL.field("COALESCE(jsonb_object_agg({0}, ({1})) FILTER (WHERE {0} IS NOT NULL), '{}')::jsonb", JSON_TYPE, key, select)
或者你做你之前提到的事情。關于這種擔憂:
...但我隨后遇到了我的 T 類型為 JsonNode 的問題,其中 DSL#coalesce 似乎將我的 coalesceTo 轉換為 varchar。
那可能是因為您使用了agg.getType()
which returnsClass<?>
而不是agg.getDataType()
which returns DataType<?>
。
但這將是最后的手段:感覺就像我離讓用戶將他們想要的任何 SQL 注入我的數據庫僅一步之遙
我不確定為什么這是一個問題。您仍然可以自己控制普通 SQL API 的使用,用戶將無法注入任意內容key
,select
因為您也控制這些元素。
添加回答
舉報