JOOQ DSL 在 LISTAGG() 中解决 ORA-01489 的方法
JOOQ DSL way of working around ORA-01489 in LISTAGG()
在 Oracle SQL 中,当生成的文本对于 VARCHAR2 来说太大时,使用 XMLAGG 而不是 LISTAGG 有这个解决方法(错误消息:ORA-01489 Result of string concat is too large
)。
SQL 示例:
LISTAGG(MY_TEXT_SNIPPET) WITHIN GROUP (order by SNIPPET_NO)
解决方法
RTRIM(XMLAGG(XMLELEMENT(e, MY_TEXT_SNIPPET,'').EXTRACT('//text()') ORDER BY SNIPPET_NO).GetClobVal(),',')
你会如何用 JOOQ 做后者?
从 jOOQ 3.14 开始支持一些 XML 函数,包括:
但是 EXTRACT()
和 GetClobVal()
都不支持这种形式。您尝试使用 XMLQUERY()
并转换为 CLOB
。
或者,与往常一样,当供应商特定的功能不受支持时,您可以求助于使用 plain SQL templating:
混合 jOOQ API 与模板
public static Field<String> listAggWorkaround(Field<?> field, Field<?> orderBy) {
return rtrim(
field("{0}.GetClobVal()", SQLDataType.CLOB,
xmlagg(field("{0}.extract('//text()')", SQLDataType.XML,
xmlelement("e", field, inline(""))
)).orderBy(orderBy)
),
inline(",")
);
}
仅使用模板
public static Field<String> listAggWorkaround(Field<?> field, Field<?> orderBy) {
return field(
"rtrim(xmlagg(xmlelement(e,{0},'').extract('//text()') order by {1}).GetClobVal(),',')",
SQLDataType.CLOB,
field, orderBy
);
}
在 Oracle SQL 中,当生成的文本对于 VARCHAR2 来说太大时,使用 XMLAGG 而不是 LISTAGG 有这个解决方法(错误消息:ORA-01489 Result of string concat is too large
)。
SQL 示例:
LISTAGG(MY_TEXT_SNIPPET) WITHIN GROUP (order by SNIPPET_NO)
解决方法
RTRIM(XMLAGG(XMLELEMENT(e, MY_TEXT_SNIPPET,'').EXTRACT('//text()') ORDER BY SNIPPET_NO).GetClobVal(),',')
你会如何用 JOOQ 做后者?
从 jOOQ 3.14 开始支持一些 XML 函数,包括:
但是 EXTRACT()
和 GetClobVal()
都不支持这种形式。您尝试使用 XMLQUERY()
并转换为 CLOB
。
或者,与往常一样,当供应商特定的功能不受支持时,您可以求助于使用 plain SQL templating:
混合 jOOQ API 与模板
public static Field<String> listAggWorkaround(Field<?> field, Field<?> orderBy) {
return rtrim(
field("{0}.GetClobVal()", SQLDataType.CLOB,
xmlagg(field("{0}.extract('//text()')", SQLDataType.XML,
xmlelement("e", field, inline(""))
)).orderBy(orderBy)
),
inline(",")
);
}
仅使用模板
public static Field<String> listAggWorkaround(Field<?> field, Field<?> orderBy) {
return field(
"rtrim(xmlagg(xmlelement(e,{0},'').extract('//text()') order by {1}).GetClobVal(),',')",
SQLDataType.CLOB,
field, orderBy
);
}