Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1082408
  • 博文数量: 145
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 3510
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-30 13:00
个人简介

About me:Oracle ACE,optimistic,passionate and harmonious. Focus on oracle programming,peformance tuning,db design, j2ee,Linux/AIX,web2.0 tech,etc

文章分类

全部博文(145)

文章存档

2023年(28)

2022年(43)

2020年(62)

2014年(3)

2013年(9)

分类: Oracle

2013-11-26 20:31:06

  Oracle SQL里有undocument function实现reverse string的功能,那么能否用其他方式实现呢?这里介绍几种方法:
1.undocument REVERSE FUNCTION
SELECT REVERSE('测试reverse') FROM dual; 
--注意中文可能乱码
SELECT REVERSE('测试reverse') FROM dual;
--2次reverse正常
SELECT reverse(REVERSE('测试reverse')) FROM dual;

2.使用utl_raw.REVERSE
SELECT utl_raw.cast_to_varchar2(utl_raw.reverse(utl_raw.cast_to_raw('测试reverse'))) FROM dual;
--中文同上


3.递归SQL实现reverse,好处,中文的可以直接reverse
--带分隔符,选不存在字符串的特殊符号
WITH t AS
  (SELECT  '测试reverse' AS str FROM dual)
  SELECT REPLACE(sys_connect_by_path(res_str, '|'), '|') AS reversed_string
  FROM (SELECT length(str) - rownum AS rn, substr(str, rownum, 1) res_str
         FROM t
         CONNECT BY rownum <= length(str))
  WHERE connect_by_isleaf = 1
  CONNECT BY rn = PRIOR rn + 1
  START WITH rn = 0;
 
 --11g r2递归with 
 WITH t (str, s, c) 
 AS (
  SELECT '测试reverse' str, CAST(NULL AS VARCHAR2(15)) s, 0
  FROM dual
  UNION ALL
  SELECT str, s || substr(str, -c - 1, 1), c + 1 FROM t WHERE c <= length(str)
)
SELECT MAX(str) str, MAX(s) rev_str FROM t;



4.使用undocument wm_concat OR 11g r2 listagg,好处,中文的可以直接reverse

SELECT REPLACE(WM_CONCAT(NAME), ',', '') REV_NAME
FROM (SELECT LEVEL, SUBSTR('测试reverse', LEVEL, 1) NAME
       FROM DUAL
       CONNECT BY LEVEL <= LENGTH('测试reverse')
       ORDER BY 1 DESC);


SELECT listagg(str) within
GROUP(
ORDER BY ord)
FROM (SELECT rownum ord, substr('测试reverse', LEVEL * -1, 1) str
       FROM dual
       CONNECT BY LEVEL <= length('测试reverse'));


当然,undocument的东西最好别用,这里11g推荐使用listagg,或者非中文的用UTL_RAW.REVERSE实现。

阅读(26396) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~