mysql 如何在JOOQ中设置@变量

j0pj023g  于 2023-08-02  发布在  Mysql
关注(0)|答案(1)|浏览(105)

如何在JOOQ中使用@variables?(或者是否有更简单的可能性来显示行号?- 注意,我需要将所选数据插入到另一个表中,并且row_number应始终从0开始!)

SET @row_number = 0;

SELECT 
    (@row_number:=@row_number + 1) AS NUM, FIRST_NAME, LAST_NAME
FROM
    AUTHOR
LIMIT 5;

字符串
这就是我认为JOOQ代码可能看起来像...

Field<Integer> num = DSL.field("@row_number:=@row_number +1", Integer.class);
DSLContext create = DSL.using(connection, dialect);
create.select(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, num)
      .from(AUTHOR)
      .limit(5)
      .fetch();


我需要执行那个吗

SET @row_number = 0;


用普通的JDBC
我在StackOverflow上找到了关于变量和JOOQ的东西-how can we have variable in jooq
编辑:我调查了更多,并阅读到这个“解决方案”的结果可能会在未来的版本中发生变化。ao我考虑将其更改为创建一个具有pk标识的临时表(从0开始),然后我有相同的结果,但没有用户变量设置和更新。

wwodge7n

wwodge7n1#

正如您所注意到的,jOOQ目前并不严格支持您的语法,因此您必须使用jOOQ API提供的普通SQL模板机制:https://www.jooq.org/doc/latest/manual/sql-building/plain-sql-templating
您已经为查询本身正确地完成了这一操作。现在,关于初始化变量,理想情况下,这是在同一个JDBC语句中完成的,而不是在一个单独的语句中完成,以防止jOOQ关闭连续执行之间的JDBC连接所引起的副作用(例如:当使用DataSourceConnectionProvider时)。因此,使用jOOQ最直接的方法是使用ExecuteListener,它只将初始化SQL字符串前置到特定语句,例如:

class InitialisingVariableListener extends DefaultExecuteListener {
    @Override
    public void renderEnd(ExecuteContext ctx) {
        ctx.sql("SET @row_number = 0;" + ctx.sql());
    }
}

字符串
并在执行查询之前将其挂接到Configuration

Field<Integer> num = DSL.field("@row_number:=@row_number +1", Integer.class);
DSLContext create = DSL.using(connection, dialect);
create.configuration().set(new InitialisingVariableListener());
create.select(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, num)
      .from(AUTHOR)
      .limit(5)
      .fetch();


如果您在多个查询中重用Configuration,您可能更愿意在其上调用derive()来创建新的Configuration,而不是set(),这会为每个人修改Configuration

其他RDBMS的注意事项

这个答案是特定于MySQL的,其中SET语句不会通过JDBC产生任何输出(更新计数)。在其他RDBMS中(例如SET会产生一个更新计数,这可能需要跳过,有关详细信息和解决方法,请参阅此处的问题:

相关问题