存储过程中以传参的方式决定排序DESC/ASC

该文章描述了一个SQL存储过程,该过程接受两个参数来决定排序方式,一个是排序列(id,name,age之一),另一个是排序方向(asc或desc)。由于JSON_ARRAYAGG函数导致原始排序丢失,作者改用CASE语句在聚合函数内部进行排序,以确保排序效果。这种方法根据v_sort_by和v_sort_dir的值来动态调整ORDERBY子句,解决了问题。
摘要由CSDN通过智能技术生成

背景:
在一个存储过程中,用了两个参数用来做排序的决定参数
v_sort_by表示按哪一列排序,(id、name、age 三选一)
v_sort_dir 表示是升序还是降序(desc、asc 二选一)
根据传参的不同实现不同的排序效果

    FUNCTION fun_get_persons(
        v_sort_by VARCHAR2,
        v_sort_dir VARCHAR2) RETURN CLOB 
    AS
        v_OUTPUT clob;
    BEGIN
    	WITH temp_t AS (SELECT * FROM table_1 (fun_get_person_helper())),
             results AS (SELECT JSON_ARRAYAGG(
                                   JSON_OBJECT(
                                        		'id' VALUE temp_t.id,
                                        		'name' VALUE temp_t.name,
                                        		'age' VALUE temp_t.age
                                        		RETURNING CLOB
                                        	  )  
                                    ORDER BY 
                                            CASE WHEN v_sort_by = 'id' AND v_sort_dir = 'desc'  THEN temp_t.id END DESC,
                                            CASE WHEN v_sort_by = 'id' AND v_sort_dir = 'asc'  THEN temp_t.id  END ASC,
                                            CASE WHEN v_sort_by = 'name' AND v_sort_dir = 'desc'  THEN temp_t.name END DESC,
                                            CASE WHEN v_sort_by = 'name' AND v_sort_dir = 'asc'  THEN temp_t.name END ASC,
                                            CASE WHEN v_sort_by = 'age' AND v_sort_dir = 'desc' THEN temp_t.age END DESC,
                                            CASE WHEN v_sort_by = 'age' AND v_sort_dir = 'asc' THEN temp_t.age END ASC                               
                                            RETURNING CLOB)               records
                        FROM temp_t
             )
        SELECT json_object('records' VALUE NVL(records, '[]') format json returning clob) data
        INTO v_OUTPUT
        FROM orders;
        RETURN v_OUTPUT;
    END fun_get_persons;

补充:
原本是把这两个参数放到fun_get_person_helper(v_sort_by,v_sort_dir)里面做排序

排序语句是这样式儿的:

SELECT * FROM table_1
ORDER BY case v_sort_dir when 'desc' then -1 else 1 end * row_number() 
                     OVER (
                     	ORDER BY 
                        	CASE v_sort_by
                            	WHEN 'id' THEN id
                                WHEN 'name' THEN name
                                WHEN 'age' THEN age
                                ELSE id
                            END
                          )

先根据v_sort_by参数决定按哪一列排,然后再根据v_sort_dir参数决定升序还是倒序,这里调用了row_number()函数获取第一次排序后的数据的行号,升序就是row_number() × 1,降序就是row_number() × -1

但是因为后面用了JSON_ARRAYAGG()函数,导致这里的排序丢失了(参考:JSON_ARRAYAGG()函数导致排序丢失的问题),白排,所以只能放到JSON_ARRAYAGG()函数里面做排序
但是在JSON_ARRAYAGG()函数里面竟然不能用row_number()函数!
这才换了一种句式解决这个问题

ORDER BY 
	CASE WHEN v_sort_by = 'id' AND v_sort_dir = 'desc'  THEN temp_t.id END DESC,
	CASE WHEN v_sort_by = 'id' AND v_sort_dir = 'asc'  THEN temp_t.id  END ASC,
    CASE WHEN v_sort_by = 'name' AND v_sort_dir = 'desc'  THEN temp_t.name END DESC,
    CASE WHEN v_sort_by = 'name' AND v_sort_dir = 'asc'  THEN temp_t.name END ASC,
    CASE WHEN v_sort_by = 'age' AND v_sort_dir = 'desc' THEN temp_t.age END DESC,
    CASE WHEN v_sort_by = 'age' AND v_sort_dir = 'asc' THEN temp_t.age END ASC

注意:

  • 记得每个CASE句子只有一个WHEN/THEN
  • 记得每个CASE句子都要加END
  • 记得在END后面加上DESC/ASC
  • 记得每个排序字段对应两个CASE语句,一个升序,一个降序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值