Oracle中的字符串类型及相关函数详解
1、概述
本文介绍String类型及相关的函数,基于当前最新的Oracle 12c 为基础作介绍。
下文将字符串简称为串。
Oracle函数的工作方式有两种:
1、根据旧的对象创建新的对象——他们对原来的信息进行修改,如改变字母的大小写。
2、告诉用户有关的信息,如一个单词或句子中有几个字符。
后续会更新另外两种处理文本的方式:Oracle中的正则表达式 和 Oracle Text工具,等文章编辑完成,会在此处添加链接。
Oracle中主要有两种字符串类型:CHAR和VARCHAR2,他们以字母,标点,数字和空格的混合形式存在。
CHAR串始终为定长的,如果设置的值长度小于CHAR列的串值,会自动填充空格。在比较CHAR串时,会为双方都补满空格后再进行比较。
VARCHAR2数据类型为边长的串(VARCHAR与VARCHAR2为同义词)。
2、字符串处理函数
2.1、总览
见下表:
2.2、连接符||及CONCAT函数
可以连接两个列名或者常量。
比如:
1
|
|
- SELECT firstName||lastName FROM USER;
如果姓名为中文还好,但是如果是英文的,这样连接会导致读起来比较困难,所以可以在中间加上常量“空格”:
1
|
|
- SELECT firstName||' '||lastName FROM USER;
使用CONCAT函数也能达到同样的效果:
1
|
|
- SELECT CONCAT(firstName,lastName) FROM USER;
结果:
但是CONCAT函数符合ANSI SQL标准,所以适合更多不同的数据库,||是Oracle专有的,使用起来更简洁。
2.3、格式统一:RPAD和LPAD
RPAD允许在列的右边填充一组字符,填充的字符可以为任何字符。LPAD从左边添加。
使用方式:
RPAD(string,length[,'set'])
LPAD(string,length[,'set'])
这里的string是数据库中的字符串列或常量,length是填充后的长度,set是用来填充的字符串。如果方括号中的内容省略了,会默认使用空格填充。
RPAD的使用:
1
|
|
- SELECT rpad(lastname,10,'_') as name from users;
结果:
LPAD的使用:
1
|
|
- SELECT lpad(lastname,10) as name from users;
结果:
2.4、修剪:LTRIM,RTRIM,TRIM
LTRIM和RTRIM从串的左边或右边删除不需要的字符。
使用方式:
RTRIM(string[,'set'])
LTRIM(string[,'set'])
如果没有设置要删除的值,默认删除空格。
还是用例子来解释,这里有一张存放书名的表,我们得到其书名列的值如下:
1
|
|
- SELECT name FROM BOOK;
这是因为录入数据的不是同一个人,导致了数据格式不一致,首先我们来试一下LTRIM函数:
1
|
|
- SELECT LTRIM(name,'《') FROM BOOK;
可以看到左边已经统一了,接下来就是右边,我们很容易就能组合使用LTRIM和RTRIM:
1
|
|
- SELECT RTRIM(LTRIM(name,'《'),'》') FROM BOOK;
可以看到,查询的结果已经统一了。可以一次删除多个字符,只需要把要删除的串设置进去即可。
我们在看一个例子,如果某个字段内容为:“the easy way”:
1
|
|
- INSERT INTO BOOK(ID,NAME) VALUES(6,'the easy way');
我们试着删除前面的the和多余的空格,于是我们执行如下脚本:
1
|
|
- select ltrim(name,'the ') from book where id = 6;
结果:asy way
发现并不是我们想要的,以为LTRIM在删除我们指定的字符串时,查找的不是这个字符串,而是里面的一个个字符,只有在第一次发现不属于我们指定的字符串中的字符时才会退出。RTRIM和TRIM的原理也是一样的。为了达到上面的目的,我们可以这样做:
1
|
|
- select ltrim(ltrim(name,'the'),' ') from book where id = 6;
这样就会输出我们想要的结果。但是还有更为简单的方式就是使用INSTR、SUBTR和DECODE函数,这在后面的文章中会介绍。
当我们两边要删除的字符是相同的的时候,就可以使用TRIM函数,如果上例中,书名也可能是"think in java"(两边都是单引号)这样的形式的话,如果想直接获取单纯的书名,就可以使用TRIM('"' from name):
1
|
|
- select trim('"' from name) from book where id=7;
注意TRIM中要删除的只能是单个字符,形如TRIM('《》' from name)是错误的!
如果要从串的某一段删除,可以使用LEADING和TRAILING字句,这时他们的作用于LTRIM和RTRIM是相同的:
1
|
|
- select trim(leading '"' from name) from book where id=7;
结果为:think in java"
2.5、大小写转换:LOWER、UPPER和INITCAP
LOWER把串或列种的任意字母转换为小写。
UPPER与LOWER相反。
INITCAP将串或列中每个单词的首字母转换成大写。
它们经常一起使用。
使用格式:
LOWER(string)
UPPER(string)
INITCAP(string)
我们可以看一下例子就清楚了:
1
|
|
- select name,upper(name),lower(name),initcap(name) from book;
结果:
可以看到INITCAP不但将首字母大写了,还将后面的字母转换为小写。
2.6、长度:LENGTH
使用LENGTH可以得到一个串的长度。
使用格式:
LENGTH(string)
例如:
1
|
|
- select name,length(name) from book;
结果:
2.7、子串:SUBSTR
使用SUBSTR函数可以提取出串的一部分。
使用格式:
SUBSTR(string,start[,count])
这个函数告诉Oracle提取string的一个子串,从start位置开始,长度为count个字符。如果不指定count,将从start开始一直到这个串结束。
如果有下面一张表:
1
|
|
- select * from phonebook;
如果我们需要不含区号的结果,可以这样:
1
|
|
- select rpad(firstname||lastname,10,'.') as name,substr(phone,5) as phone from phonebook;
结果:
其中的start参数也可以是负值(仅当值类型为varchar2时,为char时不可用),这时就从串的末尾开始截取,比如上面的例子,也可以这样:
1
|
|
- select rpad(firstname||lastname,10,'.') as name,substr(phone,-9) as phone from phonebook;
结果与前一个完全一致。
count参数值一旦指定就必须为正数,否则结果将返回null。
2.8、索引位置:INSTR
INSTR可以告诉你要搜索的字符(串)在串种的位置。
使用格式:
INSTR(string,set[,start[,occurrence]])
string为要寻找的列或常量;set为要指定的要寻找的值;start可选,默认为从串的第一个位置开始搜索;occurrence可选,为指定字符串出现的第occurrence次的位置。
我们依然来看看刚刚的例子:
1
|
|
- SELECT name FROM BOOK;
执行如下语句:
1
|
|
- select name,instr(name,'a') from book;
再带上start参数:
1
|
|
- select name,instr(name,'a',7) from book;
继续加上occurrence参数:
1
|
|
- select name,instr(name,'a',1,2) from book;
当然,我们也可以查找一个串:
1
|
|
- select name,instr(lower(name),'java') from book;
我们也经常会将INSTR函数与||、SUBSTR等函数一起使用,比如还是这个例子:
1
|
|
- select * from phonebook;
我们要将各个列查询出来组合成一个串,其中,phone中的区号不一定就得是3位区号,有些地区就是4位,我们可以使用如下语句:
1
|
|
- select firstname||lastname||':'||substr(phone,instr(phone,'-')+1) as phoneinfo from phonebook;
2.9、转码:ASCII和CHR
他们不常用。
CHR吧数值转换为等价的ASCII字符串;ASCII相反,但效果只对传递给他的值的第一个字符起作用。
一个例子:
1
|
|
- select 70,chr(70),'F',ascii('F'),ascii('FOCUS') from dual;
输出:70FF7070
3、在ORDER BY和WHERE子句中使用串函数
串函数可以直接用于WHERE子句中:
1
|
|
- select name from book where length(name)>10;
或者是ORDER BY子句中:
1
|
|
- select name from book order by length(name);
我们也可以使用前面介绍的函数用于复杂的子句,比如稍微复杂一点的:
1
|
|
- select name from book where instr(name,'a',1,2)>0 and length(name)>10;
输出:"think in java"
3.1、发音:SOUNDEX
SOUNDEX只用于WHERE子句的串函数。
他能查找在发音上类似于其他词语的单词,无需担心这两个单词是如何拼写的。
使用格式:SOUNDEX(string)
比如:
1
|
|
- select * from book where soundex(name) = soundex('java');
SOUNDEX还可以结合Oracle Text工具在文章总搜索单词,这会在后面专门介绍Oracle Text的文章中介绍。
4、小结
本文主要介绍了Oracle中字符串相关函数的使用。
有些函数可以在显示前调整内容:RPAD、LPAD、LTRIM、RTRIM、TRIM、LOWER、UPPER、INITCAP、SUBSTR等。
还有些函数告诉我们串的相关信息:LENGTH、INSTR、SOUNDEX等。
这些函数都可以单独或者组合使用。
后续会更新两篇非常相关的文章,到时会将链接添加到下面:
- Oracle中的正则表达式 Oracle Text工具