存储库-在本机查询中按订单排序不起作用

197*_*977 2 sql postgresql spring jpa native

我有一个spring数据JPA存储库(位于postgres db上),我有时需要使用nativeQuery = true选项来使用本机查询。

但是,在当前情况下,我需要传递一个order字段,并且这样做是这样的:

电话..

targetStatusHistoryRepository.findSirenAlarmTimeActivation([uuid,uuid2],"activation_name DESC", 0, 10)
Run Code Online (Sandbox Code Playgroud)

..回购方法

@Query(
        nativeQuery = true,
        value = """select
                     a.name as activation_name,
                     min(transition_from_active_in_millis),
                     max(transition_from_active_in_millis),
                     avg(transition_from_active_in_millis) from target_status_history t, activation_scenario a
                     where t.activation_uuid=a.activation_scenario_id and t.transition_from_active_in_millis > 0 and t.activation_uuid in (:activationUUIDs) group by a.name,t.activation_uuid
                     order by :orderClause offset :offset limit :limit """
)
List<Object[]> findSirenAlarmTimeActivation(@Param("activationUUIDs") List<UUID> activationUUIDs,
                                                              @Param("orderClause") String orderClause, @Param("offset") int offset, @Param("limit") int limit )
Run Code Online (Sandbox Code Playgroud)

我用DESC写了一个单元测试,然后用ASC调用,反之亦然,看来第一个调用是什么,第二个给出了相同的结果。

spe*_*593 6

如果那是一个准备好的语句,并且是ORDER BY子句中提供的绑定值,那是有效的,但是...

提供的绑定值不会解释为SQL文本。也就是说,该值将被视为一个值(如文字字符串)。它不会被视为列名或ASCor DESC关键字。

在您的语句上下文中,为:orderClause绑定占位符提供一个值,其效果将与您编写的效果相同ORDER BY 'some literal'

而且,这实际上并没有对行进行任何排序。

(至少在我用于DB2,Teradata,Oracle,SQL Server,MySQL和MariaDB(JDBC,Perl DBI,ODBC,Pro / C等)的每个SQL客户端库中都是如此。

(MyBatis确实提供了一种方便的机制,可以在SQL文本内进行变量替换,在准备之前动态更改SQL文本,但是这些替换是在准备语句之前处理的,并且不会在语句中转变为绑定占位符。)

在ORDER BY子句中使用一些精心设计的表达式可以得到一些“动态”排序。例如,我们可以使静态SQL文本如下所示:

  ORDER BY CASE WHEN :sort_param = 'name ASC'  THEN activation_name END ASC
         , CASE WHEN :sort_param = 'name DESC' THEN activation_name END DESC
Run Code Online (Sandbox Code Playgroud)

(这里的SQL文本不是动态的,实际上是静态的,就像我们写的一样。

 ORDER BY expr1 ASC
        , expr1 DESC
Run Code Online (Sandbox Code Playgroud)

“技巧”是,ORDER BY子句中的表达式有条件地返回每一行中某些列的值,或者它们正在返回一个文字(在上面的示例中为文字NULL),具体取决于绑定的值值,在执行时评估。

最终效果是我们可以“动态”获得以下任一效果:

 ORDER BY activation_name ASC, NULL DESC
Run Code Online (Sandbox Code Playgroud)

要么

 ORDER BY NULL ASC, activation_name DESC
Run Code Online (Sandbox Code Playgroud)

要么

 ORDER BY NULL ASC, NULL DESC
Run Code Online (Sandbox Code Playgroud)

取决于我们为:sort_param占位符提供什么值。