How to generate sql from template with order by parameter using jOOQ?

一笑奈何 提交于 2019-12-02 15:49:11

问题


I generate the sql template like this with jOOQ 3.11.11.

DSLContext context = new DefaultDSLContext(conf);
Query query = context.select()
    .from("table1")
    .where(DSL.field("report_date").eq(DSL.param("bizdate")))
    .orderBy(DSL.param("sort"));
String sqlTemp = context.renderNamedParams(query);

sql template:

select * from table1 where report_date = :bizdate order by :sort

The sql template is stored and the params are decided by realtime query condition.

ResultQuery resultQuery = context.resultQuery(sqlTemp, DSL.param("bizdate", "20190801"), DSL.param("sort", "id desc"));

the realtime sql:

select * from table1 where report_date = '20190801' order by 'id desc'

There is something wrong with the order by clause.

So. How to replace the order by param sort with "id desc" or "name asc" and elimenate the quotes?


回答1:


DSL.param() creates a bind variable, which is generated as ? in SQL, or :bizdate if you choose to use named parameters, or '20190801' if you choose to inline the bind variables. More about bind variables can be seen here.

You cannot use DSL.param() to generate column references or keywords. A column expression (e.g. a reference) is described in the jOOQ expression tree by the Field type. Keywords are described by the Keyword type, but you probably do not want to go this low level. Instead you want to handle some of the logic in your query expression. For example:

String sortField = "id";
SortOrder sortOrder = SortOrder.ASC;

Query query = context.select()
    .from("table1")
    .where(DSL.field("report_date").eq(DSL.param("bizdate")))
    .orderBy(DSL.field(sortField).sort(sortOrder));

The mistake you're making is to think that you can use a single SQL template for all sorts of different dynamic SQL queries, but what if you're dynamically adding another predicate? Or another join? Or another column? You'd have to build a different jOOQ expression tree anyway. Just like here. You could store two SQL strings (one for each sort order), and repeat that for each sort column.

But, instead of pre-generating a single SQL string, I recommend you extract a function that takes the input parameters and generates the query every time afresh, e.g.:

ResultQuery<?> query(String bizDate, Field<?> sortField, SortOrder sortOrder) {
    return context.selectFrom("table1")
                  .where(field("report_date").eq(bizDate))
                  .orderBy(sortField.sort(sortOrder));
}

Here is some further reading about using jOOQ for dynamic SQL:

  • https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql
  • https://blog.jooq.org/2017/01/16/a-functional-programming-approach-to-dynamic-sql-with-jooq


来源:https://stackoverflow.com/questions/57591155/how-to-generate-sql-from-template-with-order-by-parameter-using-jooq

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!