我有一个Oracle存储过程,该存储过程负责对查询数据进行分页。它接收要搜索的文本,偏移量和页码。 现在,我想添加两个新参数来对查询结果进行分页之前。我的问题是,如何指定动态顺序和方向。
现在,我现在应该使用CASE子句指定列,但是我需要添加ASC或DESC。
CREATE OR REPLACE PROCEDURE search_city_paged (
in_search_key IN VARCHAR2,
in_offset IN NUMBER,
in_num_elements IN NUMBER,
in_polling_place IN VARCHAR2,
in_order_by IN NUMBER,
in_order_dir IN VARCHAR2,
out_city OUT SYS_REFCURSOR
) AS
BEGIN
OPEN out_citizens FOR
SELECT COUNT(*) OVER (),
cit.city_code,
cit.city_name,
cit.city_zip,
cit.city_cities
FROM city cit
WHERE CATSEARCH(cit.FULL_TEXT_SEARCH, l_in_search_key, NULL)>0
ORDER BY ???
OFFSET in_offset ROWS FETCH FIRST in_num_elements ROWS ONLY;
END search_city_paged;
如果我收到新的参数1和ASC,则结果按city_code ASC排序。 如果我收到新的参数1和DESC,则结果按city_code DESC排序。 如果我收到新的参数2和ASC,则结果按city_name ASC排序。 如果我收到新的参数2和DESC,则结果将按city_name DESC排序。
而且...以相同的方式在每列上必须允许对结果进行排序。
答案 0 :(得分:2)
通过两个外部CASE
表达式,一个ASC
和一个DESC
进行排序。在第一个选项中,检查是否要对ASC
进行排序,如果不希望表达式返回常量或NULL
,即不改变顺序。对于要排序ASC
的情况,请添加一个内部CASE
表达式,该表达式返回要排序的列。类似地处理DESC
情况。
...
ORDER BY CASE
WHEN in_order_dir = 'ASC' THEN
CASE
WHEN in_order_by = 1 THEN
city_code
WHEN in_order_by = 2 THEN
city_name
...
END
END ASC,
CASE
WHEN in_order_dir = 'DESC' THEN
CASE
WHEN in_order_by = 1 THEN
city_code
WHEN in_order_by = 2 THEN
city_name
...
END
END DESC;
也许由于各列之间的类型不兼容而不得不对其进行调整,但我不能从您发布的内容中看出这一点。但是它应该传达一般的概念。
编辑:
关于类型问题:
一种可能是以保持顺序的方式将列转换为兼容的数据类型。例如,如果您有一个char_column
(类型为char
),一个date_column
和一个integer_column
(分别是date
和integer
)你可以做
to_char(date_column, 'YYYYMMDDHH24MISS')
转换日期和
lpad(11, 38, '0')
将整数转换为char
。
要做的比较干净,但是要做的工作更多(对于程序员而言,就性能而言,应该没有什么大的不同)是再次拆分表达式。即对于每个方向的列,每种类型都有一个外部CASE
。
喜欢
ORDER BY CASE
WHEN in_order_dir = 'ASC' THEN
CASE
WHEN in_order_by = 1 THEN
char_column1
WHEN in_order_by = 2 THEN
char_column2
...
END
END ASC,
CASE
WHEN in_order_dir = 'ASC' THEN
CASE
WHEN in_order_by = 3 THEN
date_column1
WHEN in_order_by = 4 THEN
date_column2
...
END
END ASC,
,对于所有类型,依此类推,对于DESC
类似。请记住,如果该列不是要在这样的CASE
之后进行排序,则会产生NULL
,并且以此排序不会影响顺序。