【问题标题】:How to generate Dynamic Order by clause in PL/SQL procedure?如何在 PL/SQL 过程中生成 Dynamic Order by 子句?
【发布时间】:2015-03-13 23:39:18
【问题描述】:

我正在尝试编写一个 PL/SQL 过程,该过程将使用 SQL 查询来获取结果。但要求是 order by 可以是动态的,主要用于对屏幕中的列进行排序。我将 2 个参数传递给此过程 - in_sort_column 和 in_sort_order。 要求是在文本列上排序是 ASC,对于数字是 DESC。 我的查询看起来像这样,没有添加 in_sort_order -

SELECT col1, col2, col3 from tabl e1 where col1 > 1000 
ORDER BY decode(in_sort_column,'col1', col1, 'col2', col2, 'col3', col3);

在这种情况下,我无法弄清楚如何使用 in_sort_order 参数。之前做过这件事的人可以帮忙吗?

谢谢

【问题讨论】:

  • 如果 in_sort_order 参数是由您已经知道的数据类型决定的,为什么还需要它?
  • 我刚刚添加了参数,因为当我尝试使用这样的查询时 - SELECT col1, col2, col3 from table e1 where col1 > 1000 ORDER BY decode(in_sort_column,'col1', col1 desc, ' col2',col2 asc,'col3',col3 asc); ...这不起作用
  • 为了使其简单而冗长,请使用 case 表达式按顺序排列。看stackoverflow.com/a/26033176/3989608

标签: sql oracle plsql


【解决方案1】:

在进行动态排序时,我建议使用 separate 子句:

order by (case when in_sort_column = 'col1' then col1 end),
         (case when in_sort_column = 'col2' then col2 end),
         (case when in_sort_column = 'col3' then col3 end)

这保证了如果列的类型不同,您不会遇到类型转换的意外问题。请注意,case 返回的 NULL 没有 else 子句。

【讨论】:

  • 这行得通,我也不需要传递 in_sort_order 参数。我将我的解码更改为这样的案例语句 - 按顺序(当 in_sort_column = 'col1' 然后 col1 结束时的情况)ASC,(当 in_sort_column = 'col2' 然后 col2 结束时的情况)DESC,(当 in_sort_column = 'col3' 然后 col3 时的情况结束) ASC
【解决方案2】:

由于要求基于数据类型,您可以在解码中取反数字列;如果 col1 是数字,其他是文本,则:

ORDER BY decode(in_sort_column, 'col1', -col1, 'col2', col2, 'col3', col3);

但这会尝试将文本列转换为数字。您可以交换解码或左右来避免这种情况,但是您随后将数字列隐式转换为字符串,然后您的数字将按字母顺序排序 - 例如,2 在 10 之后。

所以 Gordon Linoff 对大小写的使用更好,你仍然可以用它来否定 col1 值,以使数字有效地降序排序。

【讨论】:

  • 这也是我的想法 ;-) 但我还添加了date 类型列来测试数据,decode 产生了错误 ORA-00932。
  • 是的,使用 case 可以避免此类问题,正如 Gordon 已经指出的那样。
猜你喜欢
  • 1970-01-01
  • 2018-10-04
  • 1970-01-01
  • 2013-01-13
  • 2018-03-23
  • 1970-01-01
  • 1970-01-01
  • 2012-12-24
  • 1970-01-01
相关资源
最近更新 更多