说到动态排序,可以直接理解为按照指定的列及方向进行排序并返回结果集。
可能有人要说,动态生成SQL,返回游标不就O了吗。思路如此,但是途径还是会有一些误区,故分享在此。
假设有一个商品信息表tab_product,其有:浏览量(hitNum)、销量(orderNum)、发布日期(publishTime)、零售价(price)等字段。
需要按照浏览量的倒序、销量的倒序、发布日期的倒序;零售价的顺、倒序排序。每种排序规则同时只能应用一种。
例如按照人气排序:
SELECT * FROM tab_product ORDER BY hitNum DESC
按照销量排序则为:
SELECT * FROM tab_product ORDER BY orderNum DESC
如何做到按照页面交互所传入不同列以及方向进行排序呢?看看以下一个ORACLE 函数的代码片段:
OPEN result FOR
SELECT *
FROM tab_product
ORDER BY v_orderCol||' '||v_orderDir
;
return(Result);
close Result;
其中v_orderCol和v_orderDir分别是排序列名和排序方向。该过程(函数)编译没有问题,但执 行起来的结果却不是预期,但也不报错。
按照ORACLE的语法:OPEN <引用游标> FOR <SQL语句>,这里的问题却是如何区理解这里的<SQL语句>的问题。
上一代码中的SQL是按常量还是变量对待呢?该问题笔者也没有得到很好的理解,所谓百思不得其解。直接上改善后的代码:
c_sql := 'SELECT *
FROM tab_product
ORDER BY'||' '||v_orderCol||' 'v_orderDir ;
OPEN result FOR c_sql
;
return(Result);
close Result;
该语句即可得到预期结果。初步怀疑与SQL语句的解析机制有关,前一代码中SQL是逐步”拼装“的,是“变量”,
而后一代码SQL是一口气拼装的,可当做是”常量“,有点类似于JAVA编程中的final变量。
问题虽然是解决了,但显而易见,后一代码中一口气拼装SQL是多么的痛苦,如果SQL包含单引号,则需要输入2个单引号:
例如productName LIKE ‘%DVD%’ 需要写成:productName LIKE ’‘%’||v_name'%''||',够呛吧?