Oracle LPAD/RPAD函数在处理中文时的注意事项
首先看下Oracle官方对函数的定义:
The RPAD function returns an expression, right-padded to a specified length with the specified characters; or, when the expression to be padded is longer than the length specified after padding, only that portion of the expression that fits into the specified length.
RPAD函数将指定的字符串从目标字符串的右侧填充指定长度的字符串,若待填充的字符串的长度大于制定的填充长度,则会根据填充的长度对目标字符串进行截取。
函数语法
RPAD (text-exp , length [, pad-exp])
对Length填充长度的解释
关于对各个参数的解释,我们重点来看看length这个参数:
Length
The total length of the return value as it is displayed on your terminal screen. In most character sets, this is also the number of characters in the return value. However, in some multibyte character sets, the display length of a character string can differ from the number of characters in the string.
When you specify a value for length that is shorter than the length of text-exp, then this function truncates the expression to the specified length.
粗体部分大意为:返回值的总长度正如它们在你的终端屏幕上显示的长度一样,注意,是终端显示的长度,非该字符串在数据库中的实际显示长度(字节)。这在多字节支持的数据库(如简体中文,AL32UTF8等等)中尤为明显。
通过下面的一个示例来理解一下这句话:
SQL> SELECT '甲骨文' ORA_STR,
2 LENGTHB('甲骨文') ORA_STR_LENGTH,
3 RPAD('甲骨文', 10, '$') ORA_RPAD_STR,
4 LENGTHB(RPAD('甲骨文', 10, '$')) ORA_RPAD_STR_LENGTH
5 FROM dual
6 ; ORA_STR ORA_STR_LENGTH ORA_RPAD_STR ORA_RPAD_STR_LENGTH
--------- -------------- ------------- -------------------
甲骨文 9 甲骨文$$$$ 13 SQL>
我的数据库的字符集是AL32UTF8,所以一个中文字符占3个字节。在这个例子中,LENGTHB函数对字符串“甲骨文”的字节长度计算很准确,为9个字节,但是你会发现,我们用RPAD函数向字符串”甲骨文“后面填充$符号,总长度为10时,结果范围的却是”甲骨文$$$$",并不是我们期望得到的值"甲骨文$",同时也会发现,截取完后的字符串长度也并不是10个字节。
我们回到官方定义中对于返回长度Length的解释,这个长度取决于当前字符在屏幕终端显示时所占据的大小,对于中文来说,通常在屏幕上占据的是2个字节的宽度:

因此RPAD在进行填充的时候对这些字符按照两个字节去处理,所以出现了上述示例所描述的情况。这种不可预知(Sometimes)的情况对于那些输出固定字节宽度的程序来说无疑会产生问题。
解决方法
下面是针对这种问题的解决方法:
SQL> SELECT '甲骨文' ORA_STR,
2 LENGTHB('甲骨文') ORA_STR_LENGTH,
3 RPAD('甲骨文', 10, '$') ORA_RPAD_STR,
4 LENGTHB(RPAD('甲骨文', 10, '$')) ORA_RPAD_STR_LENGTH,
5 -- 解决方法
6 SUBSTRB('甲骨文' || RPAD('$', , '$'), , ) SOLUTION
7 FROM dual
8 ; ORA_STR ORA_STR_LENGTH ORA_RPAD_STR ORA_RPAD_STR_LENGTH SOLUTION
--------- -------------- ------------- ------------------- ----------
甲骨文 9 甲骨文$$$$ 13 甲骨文$ SQL>
在实际应用中,我们可以将上述方法抽象为一个函数来使用:
CREATE OR REPLACE
FUNCTION rpad2(str IN VARCHAR2,
len IN PLS_INTEGER,
pad IN VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
RETURN SUBSTRB(str || RPAD(pad, len, pad), 1, len);
END rpad2;
使用范例:
SQL> SELECT rpad2('甲骨文', 10, '$') PADDED_VALUE FROM DUAL;
PADDED_VALUE
-----------------------
甲骨文$
SQL>
参考链接
- Oracle Bug? RPAD of Japanese (kanji) character in Oracle 10gR2 UTF8 database
- Issue with LPAD/RPAD when using with Japanese data
- Oracle Documentation - RPAD
Oracle LPAD/RPAD函数在处理中文时的注意事项的更多相关文章
- oracle lpad rpad函数
学习并记录 1.情况一 ) from dual; 运行结果如下: email长度5,默认添加3个空格在左边 2.情况二 ) from dual; 运行结果如下: email长度5,截取2两个字符 3. ...
- oracle 使用count()函数进行分组计数时所踩的坑!
1.情景展示 需要对id_card字段按字符长度进行分组统计并进行计数. 2.错误方式 第一步:统计出id_card字段共存在几种情况. 第一种方式:distinct 第二种方式:group by ...
- Oracle EBS在编码方式为AL32UTF8时的注意事项
现如今的EBS系统中,为了推进国际化的进程,以及系统向全球化的扩展,在Oracle数据库的编码方式上渐渐从支持中国本土简体中文的ZHS16GBK转向了更趋于国际化的AL32UTF8编码方式.但随之而来 ...
- Oracle中Lpad函数和Rpad函数的用法
http://blog.csdn.net/woshixuye/article/details/17262307 一.Lpad函数 lpad函数将左边的字符串填充一些特定的字符其语法格式如下:lpad ...
- oracle中extract()函数----用于截取年、月、日、时、分、秒
oracle中extract()函数从oracle 9i中引入,用于从一个date或者interval类型中截取到特定的部分 语法如下: extract ( { year | month | day ...
- [转载]ORACLE日期时间函数大全
ORACLE日期时间函数大全 TO_DATE格式(以时间:2007-11-02 13:45:25为例) Year: yy two digits 两位年 ...
- ORACLE 常用字符函数
ORACLE 常用字符函数1 ASCII(arg1)返回参数arg1的十进制数字表示.如果数据库设置为ASCII,则采用的是ASCII码字符.如果设置为EBCDIC,则采用的是EBCDIC字符 sel ...
- [转]ORACLE日期时间函数大全
本文转自:http://www.cnblogs.com/chuncn/archive/2009/04/29/1381282.html ORACLE日期时间函数大全 TO_DATE格式(以时间: ::2 ...
- ORACLE单字符函数的函数
1. ASCII(C) 说明:返回C的首字符在ASCII码中相应的十进制 举例: SQL>SELECT ASCII('A') A,ASCII('a') B,ASCII( ...
随机推荐
- sql server还原数据库bak文件
RESTORE DATABASE CCC FROM DISK = 'AAA.bak' with replace, MOVE 'BBB' TO 'C:\Program Files\Microsoft ...
- MyBatis知多少(9)不同类型的数据库
并非所有的数据库都如此复杂,需要使用昂贵的数据库管理系统以及企业级的硬件.一些数 据库其实非常小,足以运行在一台老式的PC机上.所有的数据库都是不一样的.它们有各自不 同的需求和不同的挑战.iBATI ...
- 【MVC 过滤器的应用】ASP.NET MVC 如何统计 Action 方法的执行时间
代码如下: using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; u ...
- codeforce A. Design Tutorial: Learn from Math
题意:将一个数拆成两个合数的和, 输出这两个数!(这道题做的真是TMD水啊)开始的时候不知道composite numbers是啥意思,看了3遍才看懂.... 看懂之后又想用素数筛选法来做,后来决定单 ...
- Java 随机数
本章先讲解Java随机数的几种产生方式,然后通过示例对其进行演示. 广义上讲,Java中的随机数的有三种产生方式:(01). 通过System.currentTimeMillis()来获取一个当前时间 ...
- BackgroundCheck – 根据图片亮度智能切换元素样式
BackgroundCheck 是一个轻量的 JavaScript 库,能够根据元素后面的图片的亮度自动切换元素样式.例如在图片幻灯片功能中,根据图片亮度调整导航箭头的颜色,这样让图片和导航的颜色形成 ...
- Mongodb For Windows
关于 mongodb管理与安全认证 请移步这里: Mongodb For Mac OSX && 登录验证 安装mongodb 1. 官网下载 mongodb,如果嫌慢还可以前往百度云盘 ...
- CMD魔法堂:获取进程路径和PID值的方法集
一.前言 在开发发布更更新工具——更新Weblogic应用模块时,了解到更新Weblogic应用需要先关闭Weblogic应用窗口然后是清缓存.更新应用文件,最后再重启Weblogic应用窗口. ...
- UINavigationItem和UItabBarItem的区别详解
一.UINavigationItem 1> 获得方式 self.navigationItem // self是指控制器 2> 作用 可以用来设置当前控制器顶部导航栏的内容 // 设置导航栏 ...
- 安装DRBD的一些问题
安装DRBD,建议用源代码包先生成rpm包来安装,不要用直接download的rpm包,有可能会用不了,因为这跟系统内核版本有关系,在2.6.33版本以前内核没有集成drbd, A.先安装一些其它 ...