代码编织梦想

引入:

在实际操作中,俺写了这样一个Funtcion:

    FUNCTION fun_get_xxx(v_param_one VARCHAR2) RETURN CLOB AS
        v_OUTPUT CLOB;
    BEGIN
        WITH temp_table AS (
        	SELECT * FROM (
				( SELECT one.action_id,
                         two.log_time
				  FROM table_one one
                  LEFT JOIN table_two two on two.action_id = one.action_id
                  WHERE one.action_id = v_param_one
                )
               	UNION
                ( SELECT one.action_id,
                         two.log_time
                  FROM table_three three
                  LEFT JOIN table_four four on four.action_id = three.action_id
                  WHERE three.action_id = v_param_one)
                )
        	)
        	ORDER BY log_time DESC
        	
        SELECT JSON_OBJECT(
                       'numOfRecords' VALUE count(temp_table .action_id),
                       'records' VALUE (
                       		JSON_ARRAYAGG(
                                   JSON_OBJECT(
                                           'actionId'  VALUE temp_table.action_id,
                                           'logTime' VALUE temp_table.log_time
                                   )
                       		)
                       ) format json returning clob
               )
        INTO v_OUTPUT
        from temp_table;
        RETURN v_OUTPUT;
    END fun_get_xxx;

WITH子句中,对数据进行了关于log_time列的ORDER BY 排序,

因为中间用了UNION,因此是把ORDER BY子句放到了外层的SELECT语句中的,因此能保证排序不受UNION影响,

但是根据返回的结果显示,关于log_time的排序是失败的,但它并不是没有排序,而是关于action_id排序,

试过把ORDER BY子句放到UNION语句中,也不行,

然后怀疑上了那两个JSON封装函数头上,最终在JSON_ARRAYAGG()函数上找到了解决办法。

最终修改成如下:

-- 省略...
        SELECT JSON_OBJECT(
                       'numOfRecords' VALUE count(temp_table .action_id),
                       'records' VALUE (
                       		JSON_ARRAYAGG(
                                   JSON_OBJECT(
                                           'actionId'  VALUE temp_table.action_id,
                                           'logTime' VALUE temp_table.log_time
                                   )
                       		)  ORDER BY log_time DESC -- 把排序放到了这里
                       ) format json returning clob
               )
-- 省略...

原因:

先看官方文档关于JSON_ARRAYAGG()函数的结构说明:
在这里插入图片描述
可以看到JSON_ARRAYAGG()函数的结构是可以包含ORDER BY子句的。

The JSON_ARRAYAGG function is used to aggregate data from multiple rows into a single JSON array. When using this function, the data will be ordered by the unique key because the function automatically orders the data based on the order of the rows in the result set.
大概意思:
JSON_ARRAYAGG函数用于将多行数据聚合成一个JSON数组。在使用此函数时,数据将按照唯一键进行排序,因为该函数会根据结果集中行的顺序自动对数据进行排序。

所以当JSON_ARRAYAGG()函数里面没有指定ORDER BY子句的时候,他就不能保证顺序问题,不清楚在这个封装过程它有没有对数据进行重新排序。

按说在WITH中的temp_table应该是已经排好序了的,因为俺单独把那一组语句拉出来跑,得到的结果排序没问题,非常可能在进行json封装的过程中,因为没有指定ORDER BY子句,不知道按照啥条件又排序了,导致了上一次排序失效。

问了问 chatGPT:

it is possible that the ordering is lost when aggregating the results into a JSON array using the json_arrayagg function

当使用json_arrayagg函数将结果聚合到JSON数组中时,可能会丢失原来的排序。

The reason why aggregating the results into a JSON array using the json_arrayagg function can lose the ordering is because the function does not guarantee any specific order of the elements in the resulting array. The order of the elements may be affected by various factors such as the order in which they are retrieved from the database, how they are processed by the function, and other internal implementation details.

使用json_arrayagg函数将结果聚合到JSON数组中可能会失去排序的原因是因为该函数不能保证结果数组中元素的任何特定顺序。元素的顺序可能受到各种因素的影响,比如从数据库中检索元素的顺序、函数处理元素的方式以及其他内部实现细节。

所以在用到JSON_ARRAYAGG()函数且需要排序时,把排序写在JSON_ARRAYAGG()函数内才能达到想要的排序效果。
大大的乌龙~

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_31856061/article/details/131290541

oracle数据库从入门到精通系列之十六:oracle数据库和实例的主要文件-爱代码爱编程

Oracle数据库从入门到精通系列之十六:Oracle数据库和实例的主要文件 一实例相关的文件 1.参数文件parameter file 2.跟踪文件trace file

oracle 正则表达式详解(regexp-爱代码爱编程

文章目录 1 概述 2 匹配规则 3 正则函数 3.1 regexp_substr() 3.2 regexp_instr() 3.3 regexp_replace() 3.4 regexp_like() 1 概述 1. 作用:处理字符时,很强大 1 2. 分类:与下列相似,但功能更加强大(‘支持正则表达式’) (1) regexp_like : 同 lik

oracle、mysql 分页查询比较-爱代码爱编程

1、 Oracle的分页查询语句 分页查询格式: SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (SELECT * FROM TABLE_NAME) A WHERE ROWNUM <= 40 ) WHERE RN >= 21 复制 其中最内层的查询SELECT * FROM TABLE_NA