如何在Oracle中动态订购查询结果?

时间:2011-03-24 03:52:36

标签: oracle sql-order-by dynamic

SELECT   Tbl.*,
          ROWNUM RN1
        FROM
          (
            SELECT DISTINCT( LEAVEID ),
                LEAVECODE,
                LEAVENAME,
                DESCRIPTION,
                STATUS
             FROM HRM_LEAVECONFIGURATION
              WHERE
                (
                  (
                    :LEAVENAME IS NULL OR
                    UPPER( LEAVENAME ) LIKE UPPER( :LEAVENAME )
                  )
                  AND
                  (
                    :STATUS IS NULL OR
                    STATUS   = :STATUS
                  )
                  AND
                  (
                    ISFIXED <> 1 OR
                    ISFIXED IS NULL
                  )
                  AND
                  (
                    :LEVECODE         IS NULL OR
                    UPPER( LEAVECODE ) = UPPER( :LEVECODE )
                  )
                )
              ORDER BY(
                  CASE
                      (
                        SELECT   t.data_type
                          FROM user_tab_columns t
                          WHERE t.TABLE_NAME = 'HRM_LEAVECONFIGURATION' AND
                            t.COLUMN_NAME    = 'LEAVENAME'
                      )
                    WHEN 'VARCHAR2'
                    THEN 'UPPER(LEAVENAME)'
                    ELSE 'LEAVENAME'
                  END ) DESC
          )
          Tbl

这是我遇到问题的代码。

这里我传递一个字段名作为参数,根据我想要给大写函数的字段的数据类型。

例如,如果我将leavename作为要排序的列,如果leavename的数据类型是varchar2,则按upper(leavename)Descending排序,如果leavename的数据类型不是varchar,则按leavename排序。

这里我的问题是这个查询正在运行,但它没有得到订购。还有其他建议吗?

2 个答案:

答案 0 :(得分:1)

我不确定在什么情况下列的数据类型会有所不同。当然LEAVENAME总是会成为VARCHAR2?

所以你需要的就是:

  ORDER BY(
  CASE
      when :LEAVENAME is not null THEN UPPER(LEAVENAME)
    ELSE LEAVENAME
  END ) DESC

也许您的精确业务逻辑是不同的,您希望按实际传递值的任何列进行排序。在这种情况下,你应该写这样的东西:

  ORDER BY(
  CASE
      when :LEAVENAME is not null THEN UPPER(LEAVENAME)
      when :LEVECODE is not null THEN UPPER(LEVECODE)
    ELSE LEAVENAME
  END ) DESC

顺便说一下,您需要小心这些查询。他们混淆了优化器,这意味着他们可能在某些时候或者在所有时间都表现不佳。动态组装查询通常是更好的方法。

答案 1 :(得分:0)

我很确定,你不能绑定列名。

订单属于一层。您正在对要选择的结果集进行排序,但不是最终集。在查询结束时的最终Tbl之后,order by属于。