【Oracle】Oracle之SQL中的单行函数

Oracle版本:19c

一、单行函数简介

SQL函数

两种类型的SQL函数

单行函数:

  • 处理数据项

  • 接受参数并返回一个值

  • 对返回的每一行采取行动

  • 每行返回一个结果

  • 可能会修改数据类型

  • 可以嵌套

  • 接受可以是列或表达式的参数

cpp 复制代码
function_name [(arg1, arg2,...)]

二、字符函数

2.1 大小写转换函数

LOWER

cpp 复制代码
-- LOWER函数可以将字符串全部转换为小写
SQL> SELECT LOWER('HELLO WORLD') FROM DUAL;

LOWER('HELL
-----------
hello world
      
-- 使用示例:使用LOWER函数处理列进行条件匹配
-- 可见本来名字首字母为大写,但是经过处理后可以直接和全部小写的条件进行匹配
SQL> SELECT employee_id, last_name, department_id
  2  FROM   employees
  3  WHERE  LOWER(last_name) = 'higgins';

EMPLOYEE_ID LAST_NAME                 DEPARTMENT_ID
----------- ------------------------- -------------
        205 Higgins                             110

UPPER

cpp 复制代码
-- UPPER函数可以将字符串全部转换为大写
SQL> SELECT UPPER('hello world') FROM DUAL;

UPPER('HELL
-----------
HELLO WORLD

INITCAP

cpp 复制代码
-- INITCAP函数可以将字符串中所有单词的首字母转化为大写
SQL> SELECT INITCAP('hello world') FROM DUAL;

INITCAP('HE
-----------
Hello World

2.2 字符操作函数

CONCAT

cpp 复制代码
-- CONCAT函数可以将任意两个字符串连接(注意Oracle中的CONCAT函数严格限制只支持两个参数)
-- 如果需要连接多个字符串可以使用多个CONCAT嵌套,但是更加推荐使用'||'
SQL> SELECT CONCAT('HELLO','WORLD') FROM DUAL;

CONCAT('HE
----------
HELLOWORLD
       
SQL> SELECT 'HELLO' || 'WORLD' || 'HAHA' FROM DUAL;

'HELLO'||'WORL
--------------
HELLOWORLDHAHA

SUBSTR

cpp 复制代码
-- SUBSTR可以截取字符串

-- 从第3个字符开始,截取4个字符
SQL> SELECT SUBSTR('HELLOWORLD',3,4) FROM DUAL;

SUBS
----
LLOW

-- 从第3个字符开始,截取到末尾
SQL> SELECT SUBSTR('HELLOWORLD',3) FROM DUAL;

SUBSTR('
--------
LLOWORLD
       
-- 从倒数第6个字符开始,截取4个字符
SQL> SELECT SUBSTR('HELLOWORLD',-6,4) FROM DUAL;
SUBS
----
OWOR

-- 从倒数第6个字符开始,截取到末尾
SQL> SELECT SUBSTR('HELLOWORLD',-6) FROM DUAL;
SUBSTR
------
OWORLD

-- 如果起始位置超过字符串长度,则返回空字符串
SQL> SELECT SUBSTR('HELLOWORLD',13) FROM DUAL;
SUBSTR('HELLOWORLD',13)
-----------------------

-- 如果截取长度为0,则返回空字符串
SQL> SELECT SUBSTR('HELLOWORLD',1,0) FROM DUAL;
SUBSTR('HELLOWORLD',1,0)
------------------------

LENGTH

cpp 复制代码
-- 计算字符串的长度
SQL> SELECT LENGTH('HELLOWORLD') FROM DUAL;
LENGTH('HELLOWORLD')
--------------------
                  10

INSTR

cpp 复制代码
-- 在源字符串中查找目标子串的位置,返回目标子串在源字符串中的起始位置序号(从1开始计数),若未找到则返回0。
SQL> SELECT INSTR('HELLOWORLD','WO') FROM DUAL;

INSTR('HELLOWORLD','WO')
------------------------
                       6

SQL> SELECT INSTR('HELLOWORLD','W') FROM DUAL;
INSTR('HELLOWORLD','W')
-----------------------
                      6

LPAN

cpp 复制代码
-- 使用指定字符长度和补齐空位的字符,在不够长的字符串前面补齐
-- 指定长度和补齐空位的字符
SQL> SELECT LPAD(last_name,12,'-') FROM employees;
LPAD(LAST_NAME,12,'-')
------------------------------------------------
-------Urman
------Vargas
-----Vishney
-----Vollman
-------Walsh
-------Weiss
------Whalen
-----Zlotkey

107 rows selected.

RPAD

cpp 复制代码
-- 使用指定字符长度和补齐空位的字符,在不够长的字符串后面补齐
-- 指定长度和补齐空位的字符
SQL> SELECT RPAD(last_name,12,'-') FROM employees;
RPAD(LAST_NAME,12,'-')
------------------------------------------------
Urman-------
Vargas------
Vishney-----
Vollman-----
Walsh-------
Weiss-------
Whalen------
Zlotkey-----

107 rows selected.

三、函数的嵌套

单行函数可以嵌套到任何级别。

嵌套函数的执行从最里层到最外层。

示例

cpp 复制代码
-- 嵌套了UPPER和CONCAT
SQL> SELECT last_name,
  2  UPPER(CONCAT(last_name,'-test'))
  3* FROM employees;
LAST_NAME                 UPPER(CONCAT(LAST_NAME,'-TEST'
------------------------- ------------------------------
Urman                     URMAN-TEST
Vargas                    VARGAS-TEST
Vishney                   VISHNEY-TEST
Vollman                   VOLLMAN-TEST
Walsh                     WALSH-TEST
Weiss                     WEISS-TEST
Whalen                    WHALEN-TEST
Zlotkey                   ZLOTKEY-TEST

四、数字函数

ROUND

cpp 复制代码
-- 根据指定的小数位进行四舍五入
-- 指定小数位为2
SQL> SELECT ROUND(45.9635,2) FROM DUAL;

ROUND(45.9635,2)
----------------
           45.96

-- 指定小数位为3
SQL> SELECT ROUND(45.9635,3) FROM DUAL;
ROUND(45.9635,3)
----------------
          45.964
          
-- 不指定小数位或者指定为0,代表取整数
SQL> SELECT ROUND(45.93) FROM DUAL;

ROUND(45.93)
------------
          46


SQL> SELECT ROUND(45.93,0) FROM DUAL;
ROUND(45.93,0)
--------------
            46
            
-- 指定小数位为负数,代表小数点左边几位
SQL> SELECT ROUND(45.93,-1) FROM DUAL;

ROUND(45.93,-1)
---------------
             50

TRUNC

cpp 复制代码
-- 根据指定小数位进行截取,不四舍五入
-- 指定小数位为2
SQL> SELECT TRUNC(45.9635,2) FROM DUAL;
TRUNC(45.9635,2)
----------------
           45.96

-- 指定小数位为3
SQL> SELECT TRUNC(45.9635,3) FROM DUAL;
TRUNC(45.9635,3)
----------------
          45.963

-- 不指定小数位或者指定为0,代表取整数
SQL> SELECT TRUNC(45.93) FROM DUAL;

TRUNC(45.93)
------------
          45


SQL> SELECT TRUNC(45.93,0) FROM DUAL;
TRUNC(45.93,0)
--------------
            45

-- 指定小数位为负数,代表小数点左边几位
SQL> SELECT TRUNC(45.93,-1) FROM DUAL;
TRUNC(45.93,-1)
---------------
             40

CEIL

cpp 复制代码
-- 返回大于或等于指定数字的最小整数
SQL> SELECT CEIL(2.83) FROM DUAL;
CEIL(2.83)
----------
         3

-- 需要注意负数,-2比-2.83大,所以返回-2
SQL> SELECT CEIL(-2.83) FROM DUAL;

CEIL(-2.83)
-----------
         -2

FLOOR

cpp 复制代码
-- 返回等于或小于指定数字的最大整数
SQL> SELECT FLOOR(2.83) FROM DUAL;
FLOOR(2.83)
-----------
          2

-- -3比-2.83小,所以返回-3
SQL> SELECT FLOOR(-2.83) FROM DUAL;
FLOOR(-2.83)
------------
          -3

MOD

cpp 复制代码
-- 取余
SQL> SELECT MOD(9,3) FROM DUAL;

  MOD(9,3)
----------
         0

SQL> SELECT MOD(9,2) FROM DUAL;

  MOD(9,2)
----------
         1

五、对日期的处理

  • Oracle数据库以内部数字格式存储日期:世纪,年,月,日,小时,分钟和秒.

  • 默认日期显示格式为DD-MON-RR.

    • 通过仅指定年份的最后两位数字,使您能够存储20世纪21世纪的日期

    • 使您能够以相同的方式存储21世纪的20世纪日期

示例

cpp 复制代码
SQL> SELECT last_name, hire_date
  2  FROM   employees
  3* WHERE  hire_date < '01-FEB-2008';
  
LAST_NAME                 HIRE_DATE
------------------------- ---------
Jones                     17-MAR-07
Walsh                     24-APR-06
Feeney                    23-MAY-06
OConnell                  21-JUN-07
Grant                     13-JAN-08
Whalen                    17-SEP-03
Hartstein                 17-FEB-04
Fay                       17-AUG-05
Mavris                    07-JUN-02
Baer                      07-JUN-02
Higgins                   07-JUN-02

RR格式

5.1 修改当前会话的默认日期格式

可以设定时间格式为中国人适应的YYYY-MM-DD HH24:MI:SS

年 月 日 时(24时制) 分 秒

cpp 复制代码
-- 修改当前会话的默认日期格式
SQL> ALTER SESSION SET nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.


SQL> SELECT last_name, hire_date
  2* FROM employees;
  
LAST_NAME                 HIRE_DATE
------------------------- -------------------
Grant                     2008-01-13 00:00:00
Whalen                    2003-09-17 00:00:00
Hartstein                 2004-02-17 00:00:00
Fay                       2005-08-17 00:00:00
Mavris                    2002-06-07 00:00:00
Baer                      2002-06-07 00:00:00
Higgins                   2002-06-07 00:00:00
Gietz                     2002-06-07 00:00:00

107 rows selected.

5.2 查看日期

使用SYSDATE函数

SYSDATE是一个返回以下内容的函数:

  • Date

  • Time

cpp 复制代码
SQL> SELECT SYSDATE FROM DUAL;

SYSDATE
---------
14-APR-26

-- 可以修改日期格式然后再查看
SQL> ALTER SESSION SET nls_date_format='yyyy-mm-dd hh24:mi:ss';

Session altered.

SQL> SELECT SYSDATE FROM DUAL;

SYSDATE
-------------------
2026-04-14 14:38:49

使用CURRENT_DATE 和 CURRENT_TIMESTAMP函数

CURRENT_DATE 从用户会话返回当前日期。

CURRENT_TIMESTAMP 从用户会话返回当前日期和时间。

cpp 复制代码
SQL> SELECT CURRENT_DATE ,CURRENT_TIMESTAMP FROM DUAL;
CURRENT_DATE        CURRENT_TIMESTAMP
------------------- ---------------------------------------------
2026-04-14 14:43:55 14-APR-26 02.43.55.257266000 PM ASIA/SHANGHAI

5.3 日期的计算

从日期中添加或减去一个数字,以得到结果日期值。

减去两个日期以找出这些日期之间的天数。

通过将小时数除以24,可以在日期中加上小时。

对日期使用算术运算符

cpp 复制代码
-- 计算部分ID为90的员工入职了多少周
SQL> SELECT last_name, (SYSDATE-hire_date)/7 AS WEEKS
  2  FROM   employees
  3  WHERE  department_id = 90;

LAST_NAME                      WEEKS
------------------------- ----------
King                      1191.08786
Kochhar                     1072.945
De Haan                   1317.51643

5.4 日期处理函数

MONTHS_BETWEEN

MONTHS_BETWEEN函数用于精确计算两个日期之间的月份数差值,可返回包含小数部分的精确结果,适用于需要高精度日期差计算的业务场景。

cpp 复制代码
SQL> SELECT MONTHS_BETWEEN('2026-09-09','2001-01-01') FROM DUAL;
MONTHS_BETWEEN('2026-09-09','2001-01-01')
-----------------------------------------
                               308.258065

ADD_MONTHS

ADD_MONTHS函数用于在指定日期上精确增加或减少指定的月份数,自动处理月末日期转换,是Oracle数据库中处理月份增减的核心函数。

cpp 复制代码
SQL> SELECT ADD_MONTHS('2026-04-14',1) FROM DUAL;
ADD_MONTHS('2026-04
-------------------
2026-05-14 00:00:00


SQL> SELECT ADD_MONTHS('2026-04-14',1.9) FROM DUAL;
ADD_MONTHS('2026-04
-------------------
2026-05-14 00:00:00

NEXT_DAY

NEXT_DAY函数用于返回指定日期之后的下一个指定星期几的日期,是Oracle数据库中处理周计算的核心函数,支持通过字符串或数字指定目标星期。

cpp 复制代码
-- 返回最接近指定的日期2026-04-14的星期五的日期,也就是2026-04-17
SQL> SELECT NEXT_DAY('2026-04-14','FRIDAY') FROM DUAL;
NEXT_DAY('2026-04-1
-------------------
2026-04-17 00:00:00

LAST_DAY

LAST_DAY函数是Oracle数据库中用于返回指定日期所在月份最后一天的核心日期函数,能够自动处理不同月份天数差异及闰年情况,无需手动判断月末日期。

cpp 复制代码
-- 返回指定日期的所在月份的最后一天
SQL> SELECT LAST_DAY('2026-04-14') FROM DUAL;
LAST_DAY('2026-04-1
-------------------
2026-04-30 00:00:00

使用ROUND和TRUNC函数

ROUND函数处理日期

cpp 复制代码
-- ROUND在处理MOUNTH这种,应该知道16号之前都是返回本月的一号的零时零点零分,16号之后(含16号)都是返回下个月1号的零时零点零分
SQL> SELECT ROUND(TO_DATE('2026-04-14','YYYY-MM-DD'),'MONTH') FROM DUAL;

ROUND(TO_DATE('2026
-------------------
2026-04-01 00:00:00
              
-- ROUND在处理YEAR这种,应该知道过了6月30号,也就是从7月1号开始都是返回下一年的一月一号的零时零点零分,6月30号(含30号当天)都是返回本年的一月一号的零时零点零分
SQL> SELECT ROUND(TO_DATE('2020-07-01 00:24:04','YYYY-MM-DD HH24:MI:SS'),'YEAR') FROM DUAL;

ROUND(TO_DATE('2020
-------------------
2021-01-01 00:00:00

TRUNC函数处理日期

cpp 复制代码
-- TRUNC在处理MONTH这种,无论你是月初 月中还是月末都返回本月的1号的零时零点零分
SQL> SELECT TRUNC(TO_DATE('2020-10-31 00:00:00','YYYY-MM-DD HH24:MI:SS'),'MONTH') FROM DUAL;

TRUNC(TO_DATE('2020
-------------------
2020-10-01 00:00:00

-- TRUNC在处理YEAR这种,无论你是年初 年中还是年末都返回本年的一月一号的零时零点零分
SQL> SELECT TRUNC(TO_DATE('2020-12-31 00:24:04','YYYY-MM-DD HH24:MI:SS'),'YEAR') FROM DUAL;

TRUNC(TO_DATE('2020
-------------------
2020-01-01 00:00:00
相关推荐
成都被卷死的程序员2 小时前
RustDesk 自建远程控制服务器部署全记录(含错误排查与最终方案)
运维·服务器
2201_756847332 小时前
mysql字段长度不够用了怎么办_使用alter table扩大varchar长度
jvm·数据库·python
overmind2 小时前
oeasy Python 120[专业选修]列表_直接赋值_浅拷贝_shallowcopy_深拷贝_deepcopy
linux·windows·python
小宋0012 小时前
Ubuntu Terminator(多开并行终端工具)
linux·运维·ubuntu
aq55356002 小时前
Laravel4.x革命性升级:现代PHP开发新纪元
数据库·oracle
Wyawsl2 小时前
keepalived高可用与负载均衡笔记
运维·笔记·负载均衡
小尔¥2 小时前
keepalived高可用与负载均衡
linux·运维·负载均衡
李李李li2 小时前
vmware各种版本下载链接-github
linux·ubuntu·开源软件
残 风2 小时前
linux(Xshell、Xterm)如何搭建隧道间接访问目标服务网站教程
linux·运维·php·信息与通信