如何在Oracle

时间:2019-04-05 16:54:27

标签: sql plsql oracle11g sql-order-by oracle12c

我有一个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排序。

而且...以相同的方式在每列上必须允许对结果进行排序。

1 个答案:

答案 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(分别是dateinteger)你可以做

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,并且以此排序不会影响顺序。