函数就是和 java 语言之中的方法的功能是一样的,都是为了完成某些特定操作的功能支持,而在 oracle 数据库里面也包含了大量的单行函数,这些函数掌握了以后,可以方便的帮助进行数据库的相关开发。
对开发者而言,最为重要的就是 sql 语法和单行函数,可是 oracle 中的单行函数的数量是非常多的。本章只讲解使用,后面会讲解如何去开发用户自己的函数(pl/sql 编程)
funcation_name(列|表达式[,参数1,参数2,])
函数名称(列 | 表达式 | 数值),而且在oracle 书中只讲解基本的一些单行函数。
no. | 函数名称 | 描述 |
---|---|---|
1 | upper(列|字符串) | 将字符串的内容全部转大写 |
2 | lower(列|字符串) | 将字符串的内容全部转小写 |
3 | initcap(列|字符串) | 将字符串的开头首字母大写 |
4 | replace(列|字符串,新的字符串) | 使用新的字符串替换旧的字符串 |
5 | length(列|字符串) | 求出字符串长度 |
6 | substr(列|字符串,开始点[,长度]) | 字符串截取 |
7 | ascii(字符) | 返回与指定字符对应的十进制数字 |
8 | chr(数字) | 给出一个整数,并返回与之对应的字符 |
9 | rpad(列|字符串,长度,填充字符) lpad(列|字符串,长度,填充字符) |
在左或右填充指定长度字符串 |
10 | ltrim(字符串) , rtrim(字符串) | 去掉左或右空格 |
11 | trim(列|字符串) | 去掉左右空格 |
12 | instr(列|字符串,要查找的字符串,开始位置,出现位置) | 查找一个字符串是否在指定位置上出现 |
scott 用户下: select upper('li xing hua') form emp;
范例:验证 upper() 和 lower() 函数
select upper('li xing hua'),lower('mldn') form dual;
范例:现在查询出雇员姓名是“smith”的完整信息,但是由于失误,没有考虑到大小写问题,此时可以使用upper() 函数将全部内容变为大写。
select * form emp where ename = upper('smith');
范例:查询所有雇员姓名,要求每个雇员的姓名以首字母大写的形式出现
select ename 原始姓名,initcap(ename) 姓名开头首字母大写 form emp;
范例:查询所有雇员信息,要求将雇员姓名中所有的字母“a”替换成“_”
select ename,replace(ename,'a','_') form emp;
范例:查出姓名长度是5的所有雇员信息
select * form emp where length(ename) = 5;
范例:查询出雇员姓名前三个字母是“jam”的雇员信息
select * form emp where substr(ename,1,3) = 'jam'; 或者: select * form emp where substr(ename,0,3) = 'jam';
范例: 查询所有10部门雇员姓名,但不显示每个雇员姓名的前三个字母
select ename 原姓名,substr(ename,3) 截取之后的姓名 form emp where deptno = 10;
范例:显示每个雇员姓名及姓名的后三个字母
要想截取每个姓名之中的后三个,首先要解决的问题是开始点,从一个指定的开始点一直截取到结尾,可是每个雇员的姓名长度是不同的,那么开始点如何确定呢?
select ename 原始姓名,substr(ename,length(ename) - 2) 截取之后的姓名 form emp where deptno = 10;
select ename 原始姓名,substr(ename,-3) 截取之后的姓名 form emp where deptno = 10;
现在很明显使用第二种最方便,这个也属于 oracle 的特色,不过需要注意的是:java 语言的字符串下标还是从0开始,而且 java 里的 substring() 方法是不能设置负数的。
面试题:请问 oracle 中的 substr() 函数的下标开始点是从0还是1开始?
答:可以设置为0,也可以设置为1,即使使用了0,那么最终的结果也会将其定义为1。
范例:返回指定字符的 ascii 码
select ascii('a'),ascii('l') form dual;
范例:验证 chr() 函数,将ascii 码变回字符
select chr(100) form dual;
范例:去掉字符串左边空格 - ltrim() ,去掉右边空格 - rtrim()
select ' mldn lixinghua ' 原始字符串,ltrim(' ') 去掉左空格 form dual; select ' mldn lixinghua ' 原始字符串,rtrim(' ') 去掉右空格 form dual;
范例:去掉左右空格
select ' mldn lixinghua ' 原始字符串,trim(' ') 去掉左右空格 form dual;
范例:字符串左填充 - lpad() ,字符串右填充 - rpad()
select lpad('mldn',10,'*') lpad函数使用,rpad('mldn',10,'*') rpad函数使用, lpad(rpad('mldn',10,'*'),16,'*') 组合使用 form dual;
范例:字符串查找 - instr()
select instr('mldn java','mldn') 查找得到, instr('mldn java','java') 查找得到, instr('mldn java','java') 查找不到 form dual;
no. | 函数名称 | 描述 |
---|---|---|
1 | round(数字[,保留小数]) | 对小数进行四舍五入,可以指定保留位数,如果不指定,则表示将小数点之后的数字全部进行四舍五入 |
2 | trunc(数字[,截取位数]) | 保留指定位数的小数,如果不指定,则表示不保留小数 |
3 | mod(数字,数字) | 取模 |
范例:验证 round() 函数的使用
select round(789.652) 不保留小数, round(789.652,2) 不保留小数, round(789.652,-1) 不保留小数, from dual;
范例:列出每个雇员的一些基本信息和日工资情况
select empno,ename,job,hiredate,sal,round(sal/30,2) 日薪金 from emp;
范例:验证 trunc() 函数的使用
select trunc(789.652) 截取小数, trunc(789.652,2) 截取2位小数, trunc(789.652,-2) 取整 from dual;
范例:mod() 函数验证,模就是取余
select mod(10,3) from dual;
select empno,ename,sysdate from emp;
select sysdate from dual;
alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';
select sysdate from dual;
更改的日期显示格式在关闭窗口重新打开后就会还原了
可是绝对不会存在 “日期 + 日期” 的计算,下面为其验证。
select sysdate+3 三天之后的日期, sysdate-3 三天之前的日期 from dual;
范例:查询出每个雇员的到今天为止的雇佣天数,以及十天前每天雇员的雇佣天数
select empno 雇员编号, ename 雇员姓名, sysdate-hiredate 雇佣天数, (sysdate-10)-hiredate 10天前雇佣天数 from emp;
select empno 雇员编号, ename 雇员姓名, trunc(sysdate-hiredate) 雇佣天数, trunc((sysdate-10)-hiredate) 10天前雇佣天数 from emp;
no. | 函数名称 | 描述 |
---|---|---|
1 | add_months(日期,数字) | 在指定的日期上加入指定的月数,求出新的日期 |
2 | months_between(日期1,日期2) | 求出两个日期间的雇佣月数 |
3 | next_day(日期,星期数) | 求出下一个星期几的具体日期 |
4 | last_day(日期) | 求出指定日期所在月的最后一天日期 |
5 | extract(格式 from 数据) | 日期时间分隔,或计算给定两个日期的间隔 |
范例:验证 add_months() 函数
select sysdate, add_months(sysdate,3) 三个月之后的日期, add_months(sysdate,-3) 三个月之前的日期, add_months(sysdate,60) 六十个月之后的日期, from dual;
范例:要求显示所有雇员在被雇佣三个月之后的日期
select empno,ename,job,sal,hiredate,add_months(hiredate,3) from emp;
范例:验证 next_day() 函数
select sysdate, next_day(sysdate,'星期日') 下一个星期日, next_day(sysdate,'星期一') 下一个星期一 from dual;
范例:last_day() 函数验证,求当月的最后一天
select sysdate, last_day(sysdate) from dual;
范例:查询所有是在其雇佣所在月的倒数第三天被公司雇佣的完整雇佣信息
select empno,ename,job,hiredate,last_day(hiredate) from emp where last_day(hiredate)-2=hiredate;
范例:months_between() 函数的验证:查询出每个雇员的编号、姓名、雇员佣日期,雇佣的月数及年份
select empno 雇员编号, ename 雇员姓名, hiredate 雇佣日期, trunc(months_between(sysdate,hiredate)) 雇佣总月数, trunc(months_between(sysdate,hiredate)/12) 雇佣总年数 from emp;
范例:查询出每个雇员的编号、姓名、雇佣日期、已雇佣的年数、月数、天数
select empno 雇员编号, ename 雇员姓名, hiredate 雇佣日期, trunc(months_between(sysdate,hiredate)/12) 雇佣总年数 from emp;
select empno 雇员编号, ename 雇员姓名, hiredate 雇佣日期, trunc(months_between(sysdate,hiredate)/12) 已雇佣年数, trunc(mod(months_between(sysdate,hiredate),12)) 已雇佣月数 from emp;
select empno 雇员编号, ename 雇员姓名, hiredate 雇佣日期, trunc(months_between(sysdate,hiredate)/12) 已雇佣年数, trunc(mod(months_between(sysdate,hiredate),12)) 已雇佣月数, trunc(sysdate - add_months(hiredate,months_between(sysdate,hiredate))) 已雇佣天数 from emp;
范例:extract() 函数
extract ([year | month | day | hour | minute | second] | [timezone_hour | timezone_minute] | [timezone_region | timezone_abbr] from [日期(date_value) | 时间间隔(interval_value)]);
范例:从日期时间之中取出年、月、日数据
select extract(year from date '2001-09-19') years, extract(month from date '2001-09-19') months, extract(day from date '2001-09-19') days from dual;
select sysdate,systimestamp from dual;
范例:从时间戳之中取出年、月、日、时、分、秒
select extract(year from systimestamp) years, extract(month from systimestamp) months, extract(day from systimestamp) days, extract(hour from systimestamp) hours, extract(minute from systimestamp) minutes, extract(second from systimestamp) seconds from dual;
范例:取得两个日期之间的间隔
select extract(day from to_timestamp('1982-08-13 12:17:57','yyyy-mm-dd hh24:mi:ss') - to_timestamp('1981-09-27 09:08:33','yyyy-mm-dd hh24:mi:ss')) days from dual;
范例:取得两个日期时间之间间隔的天、时、分、秒
select extract(day from datetime_one - datetime_two) days, extract(hour from datetime_one - datetime_two) hours, extract(minute from datetime_one - datetime_two) minutes, extract(second from datetime_one - datetime_two) seconds from ( select to_timestamp('1982-08-13 12:17:57','yyyy-mm-dd hh24:mi:ss') datetime_one, to_timestamp('1981-09-27 09:08:33','yyyy-mm-dd hh24:mi:ss') datetime_two from dual);
select extract(day from to_timestamp('1982-08-13 12:17:57','yyyy-mm-dd hh24:mi:ss') - to_timestamp('1981-09-27 09:08:33','yyyy-mm-dd hh24:mi:ss')) days, extract(hour from to_timestamp('1982-08-13 12:17:57','yyyy-mm-dd hh24:mi:ss') - to_timestamp('1981-09-27 09:08:33','yyyy-mm-dd hh24:mi:ss')) hours, extract(minute from to_timestamp('1982-08-13 12:17:57','yyyy-mm-dd hh24:mi:ss') - to_timestamp('1981-09-27 09:08:33','yyyy-mm-dd hh24:mi:ss')) minutes, extract(second from to_timestamp('1982-08-13 12:17:57','yyyy-mm-dd hh24:mi:ss') - to_timestamp('1981-09-27 09:08:33','yyyy-mm-dd hh24:mi:ss')) seconds from dual;
no. | 函数名称 | 描述 |
---|---|---|
1 | to_char(日期|数字|列, 转换格式) | 将指定的数据按照指定的格式变为字符串型 |
2 | to_date(字符串|列, 转换格式) | 将指定的字符串按照指定的格式变为date型 |
3 | to_number(字符串|列) | 将指定的数据类型变为数字型 |
日期格式化标记:
no. | 转换格式 | 描述 |
---|---|---|
1 | yyyy | 完整的年份数字表示,年有四位,所以使用4个y |
2 | y,yyy | 带逗号的年 |
3 | yyy | 年的后三位 |
4 | yy | 年的后两位 |
5 | y | 年的最后一位 |
6 | year | 年份的文字表示,直接表示四位的年 |
7 | month | 月份的文字表示,直接表示两位的月 |
8 | mm | 用两位数字来表示月份,月有两位,使用两个m |
9 | day | 天数的文字表示 |
10 | ddd | 表示一年里的天数(001~366) |
11 | dd | 表示一月里的天数(01~31) |
12 | d | 表示一周里的天数(1~7) |
13 | dy | 用文字表示星期几 |
14 | ww | 表示一年里的周数 |
15 | w | 表示一月里的周数 |
16 | hh | 表示12小时制,小时是两位数字,使用两个h |
17 | hh24 | 表示24小时制 |
18 | mi | 表示分钟 |
19 | ss | 表示秒,秒是两位数字,使用两个s |
20 | sssss | 午夜之后的秒数字表示(0~86399) |
21 | am|pm (a.m | p.m) | 表示上午或下午 |
22 | fm | 去掉查询后的前导0,该标记用于时间模板的后缀 |
范例:格式化日期时间
select sysdate 当前系统时间, to_char(sysdate,'yyyy-mm-dd') 格式化日期, to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') 格式化日期时间, to_char(sysdate,'fmyyyy-mm-dd hh24:mi:ss') 去掉前导0的时间 from dual;
范例:使用其他方式格式化年、月、日
select sysdate 当前系统时间, to_char(sysdate,'year-month-day') 格式化日期 from dual; 或者: select sysdate 当前系统时间, to_char(sysdate,'year-month-dy') 格式化日期 from dual;
范例:查询出所有在每年2月份雇佣的雇员信息
select * from emp where to_char(hiredate,'mm') = 2; 或者: select * from emp where to_char(hiredate,'mm') = '02';
范例:将每个雇员的雇佣日期进行格式化显示,要求所有的雇佣日期可以按照“年-月-日”的形式显示,也可将雇佣的年、月、日拆开分别显示
select empno,ename,job,hiredate, to_char(hiredate,'yyyy-mm-dd') 格式化雇佣日期, to_char(hiredate,'yyyy') 年, to_char(hiredate,'mm') 月, to_char(hiredate,'dd') 日 from emp;
数字格式化标记
no. | 转换格式 | 描述 |
---|---|---|
1 | 9 | 表示一位数字 |
2 | 0 | 表示前导0 |
3 | $ | 将货币的符号信息显示为美元符号 |
4 | l | 根据语言环境不同,自动选择货币符号 |
5 | . | 显示小数点 |
6 | , | 显示千位符 |
范例:格式化数字显示
select to_char(987654321.789,'999,999,999,999.9999') 格式化数字, to_char(987654321.789,'000,000,000,000.0000') 格式化数字 from dual;
select to_char(987654321.789,'l999,999,999,999.9999') 显示货币, to_char(987654321.789,'$999,999,999,999.9999') 显示美元 from dual;
范例:转换时间显示
select to_date('1979-09-19','yyyy-mm-dd') from dual;
范例:时间戳转换
select to_timestamp('1981-09-27 18:07:10','yyyy-mm-dd hh24:mi:ss') datetime from dual;
范例:将字符串变为数字
select to_number('09') + to_number('19') 加法操作, to_number('09') * to_number('19') 乘法操作 from dual;
select '09' + '19' 加法操作, '09' * '19' 乘法操作 from dual;
no. | 函数名称 | 描述 |
---|---|---|
1 | nvl(数字|列 , 默认值) | 如果显示的数字是null的话,则使用默认数值表示 |
2 | nvl2(数字|列,返回结果一(不为空显示),返回结果二(为空显示)) | 判断指定的列是否是null,如果不为null则返回结果一,为空则返回结果二 |
3 | nullif(表达式一,表达式二) | 比较表达式一和表达式二的结果是否相等,如果相等返回null,如果不相等返回表达式一 |
4 | decode(列|值,判断值1,显示结果1,判断值2,显示结果2,...,默认值) | 多值判断,如果某一个列(或一个值)与判断值相同,则使用指定的显示结果输出,如果没有满足条件,在显示默认值 |
5 | case 列|数值 when 表达式1 then 显示结果1 ... else 表达式n ... end | 用于实现多条件判断,在when之后编写条件,而在then之后编写条件满足的显示操作,如果都不满足则使用else 中的表达式处理 |
6 | coalesce(表达式1,表达式2,...表达式n) | 将表达式逐个判断,如果表达式1的内容是null,则显示表达式2,如果表达式2的内容是null,则显示表达式3,依次类推,如果表达式n的结果还是null,则返回null |
范例:查询出每个雇员的编号、姓名、职位、雇佣日期、年薪
select empno,ename,job,hiredate,(sal+comm)*12 年薪,sal,comm from emp;
范例:验证 nvl()
select nvl(null,0),nvl(3,0) from dual;
select empno,ename,job,hiredate,(sal+nvl(comm,0))*12 年薪,sal,comm from emp;
范例:查询每个雇员的编号、姓名、年薪(sal + comm)、基本工资、奖金
select empno,ename,job,hiredate,nvl2(comm,sal+comm,sal),sal,comm from emp;
范例:验证 nullif() 函数
select nullif(1,1),nullif(1,2) from dual;
范例:查询雇员编号、姓名、职位,比较姓名和职位的长度
select empno,ename,job,length(ename),length(job),nullif(length(ename),length(job)) nullif from emp;
decode() 函数是 oracle 中最有特色的一个函数,decode() 函数类似于程序中的 if...else if...else ,但是判断的内容都是一个具体的值,语法如下:
decode(列|表达式, 值1, 输出结果, 值2, 输出结果, ..., 默认值)
范例:测试decode() 函数
select decode(2,1,'内容为一',2,'内容为二'), decode(2,1,'内容为一','没有条件满足') from dual;
范例:现在雇员表中的工作有以下几种:clerk:业务员, salesman:销售人员, manager:经理, analyst:分析员, president:总裁 ,要求查询雇员的姓名、职位、基本工资等信息,但是要求将所有的职位信息都替换为中文显示。
select ename,sal, decode(job, 'clerk','业务员', 'salesman','销售人员', 'manager','经理', 'analyst','分析员', 'president','总裁') job from emp;
范例:显示每个雇员的工资、姓名、职位,同时显示新的工资(新的工资标准:办事员增长10%,销售人员增长20%,经理增长30%,其他职位的人增长50%)
select ename,sal, case job when 'clerk' then sal * 1.1 when 'salesman' then sal * 1.2 when 'manager' then sal * 1.3 else sal * 1.5 end 新工资 from emp;
范例:验证 coalesce() 函数
select ename,sal,comm,coalesce(comm,100,2000), coalesce(comm,null,null) from emp;
说明:本学习资料是根据李兴华的oracle开发实战经典整理
如对本文有疑问, 点击进行留言回复!!
oracle:docker镜像部署11g 创建用户名,远程连接
网友评论