Oracle内置函数及自定义函数

一、Oracle内置函数
1. 单行函数(每行输入返回一个结果)
(1) 字符函数

函数 描述 示例
LOWER(str) 转为小写 LOWER('Oracle') → 'oracle'
UPPER(str) 转为大写 UPPER('sql') → 'SQL'
SUBSTR(str, start, len) 截取子字符串 SUBSTR('Database', 2, 4) → 'ata'
INSTR(str, substr) 查找子字符串位置 INSTR('Hello', 'l') → 3
REPLACE(str, old, new) 替换字符串 REPLACE('abcdbc', 'bc', 'x') → 'axdx'
TRIM([LEADING|TRAILING|BOTH] 'c' FROM str) 去除首尾字符 TRIM(BOTH 'x' FROM 'xxSQLxx') → 'SQL'

(2) 数字函数

函数 描述 示例
ROUND(n, decimals) 四舍五入 ROUND(123.456, 2) → 123.46
TRUNC(n, decimals) 截断数值 TRUNC(123.456, -1) → 120
MOD(n1, n2) 取余数 MOD(10, 3) → 1
CEIL(n) 向上取整 CEIL(123.1) → 124

(3) 日期函数

函数 描述 示例
SYSDATE 当前系统日期和时间 SELECT SYSDATE FROM dual; → 2023-10-05 14:30
ADD_MONTHS(date, n) 添加月份 ADD_MONTHS('2023-01-31', 1) → 2023-02-28
MONTHS_BETWEEN(date1, date2) 计算月份差 MONTHS_BETWEEN('2023-12-31', '2023-01-01') → 11
TO_CHAR(date, 'format') 日期转字符串 TO_CHAR(SYSDATE, 'YYYY-MM-DD') → '2023-10-05'

(4) 转换函数

函数 描述 示例
TO_NUMBER(str) 字符串转数字 TO_NUMBER('123.45') → 123.45
TO_DATE(str, 'format') 字符串转日期 TO_DATE('2023-10', 'YYYY-MM') → 2023-10-01
NVL(expr1, expr2) 空值替换 NVL(NULL, '默认值') → '默认值'
COALESCE(expr1, expr2, ...) 返回第一个非空值 COALESCE(NULL, NULL, '值') → '值'

2. 聚合函数(多行输入返回单个结果)

函数 描述 示例
SUM(col) 求和 SELECT SUM(salary) FROM emp;
AVG(col) 平均值 SELECT AVG(age) FROM students;
COUNT(*) 统计行数 COUNT(*) FROM orders;
MAX(col)/MIN(col) 最大/最小值 SELECT MAX(price) FROM products;

3. 分析函数(窗口函数)

函数 描述 示例
ROW_NUMBER() OVER(...) 行号 SELECT name, ROW_NUMBER() OVER (ORDER BY salary DESC) FROM emp;
RANK() OVER(...) 排名(允许并列) SELECT dept, RANK() OVER (PARTITION BY dept ORDER BY sales) FROM sales_data;
LAG(col, n) OVER(...) 获取前n行数据 LAG(salary, 1) OVER (ORDER BY hire_date)

二、自定义函数
1. 创建函数

sql 复制代码
--语法:
CREATE OR REPLACE FUNCTION function_name (
    param1 [IN|OUT|IN OUT] datatype,
    ...
) RETURN return_type
IS
    -- 声明变量
BEGIN
    -- 逻辑代码
    RETURN value;
EXCEPTION
    -- 异常处理
END;

-- 示例:根据员工ID查询工资等级
CREATE OR REPLACE FUNCTION get_salary_grade (
    emp_id IN NUMBER
) RETURN VARCHAR2
IS
    v_salary NUMBER;
BEGIN
    SELECT salary INTO v_salary FROM emp WHERE employee_id = emp_id;
    IF v_salary > 10000 THEN RETURN 'A';
    ELSIF v_salary > 5000 THEN RETURN 'B';
    ELSE RETURN 'C';
    END IF;
EXCEPTION
    WHEN NO_DATA_FOUND THEN RETURN '未找到员工';
END;

2. 调用函数

sql 复制代码
-- 在SQL中调用:
SELECT get_salary_grade(1001) FROM dual;

--在PL/SQL块中调用:
DECLARE
    grade VARCHAR2(10);
BEGIN
    grade := get_salary_grade(1001);
    DBMS_OUTPUT.PUT_LINE('等级:' || grade);
END;

3. 高级功能
(1) 参数模式
IN(默认): 输入参数,不可修改。
OUT: 输出参数,用于返回结果。
IN OUT: 输入输出参数。

(2) 确定性函数
标记为 DETERMINISTIC ,输入相同则结果相同,提升性能。

sql 复制代码
CREATE FUNCTION calculate_hash(id NUMBER) RETURN NUMBER DETERMINISTIC IS
BEGIN
    RETURN DBMS_CRYPTO.HASH(id); -- 固定输入生成固定哈希
END;

(3) 递归函数

处理树形数据,例如生成层级路径:

sql 复制代码
CREATE FUNCTION get_employee_path(emp_id NUMBER) RETURN VARCHAR2 IS
    v_path VARCHAR2(200);
    v_manager_id NUMBER;
BEGIN
    SELECT manager_id INTO v_manager_id FROM emp WHERE employee_id = emp_id;
    IF v_manager_id IS NULL THEN
        RETURN TO_CHAR(emp_id);
    ELSE
        RETURN get_employee_path(v_manager_id) || '->' || TO_CHAR(emp_id);
    END IF;
END;

三、内置函数 vs 自定义函数

对比项 内置函数 自定义函数
来源 Oracle预定义 用户编写
性能 高度优化 取决于逻辑复杂度
灵活性 功能固定 可定制业务逻辑
应用场景 通用数据处理(如字符串、日期) 特定业务规则(如工资计算、数据校验)

四、总结

优先使用内置函数: 性能更优,减少开发成本。
限制自定义函数复杂度: 避免在函数中嵌套过多SQL或循环。
异常处理: 自定义函数需捕获NO_DATA_FOUND等异常,避免程序中断。
文档注释: 为自定义函数添加注释,说明用途、参数及返回值。

相关推荐
hnlucky17 分钟前
《Zabbix Proxy分布式监控实战:从安装到配置全解析》
数据库·分布式·学习·adb·zabbix·集成学习·proxy模式
Catfood_Eason26 分钟前
初识MySQL
数据库·mysql
光电大美美-见合八方中国芯1 小时前
【平面波导外腔激光器专题系列】1064nm单纵模平面波导外腔激光器‌
网络·数据库·人工智能·算法·平面·性能优化
时序数据说2 小时前
通过Linux系统服务管理IoTDB集群的高效方法
大数据·linux·运维·数据库·开源·时序数据库·iotdb
CopyLower2 小时前
解决 Redis 缓存与数据库一致性问题的技术指南
数据库·redis·缓存
多多*2 小时前
分布式ID设计 数据库主键自增
数据库·sql·算法·http·leetcode·oracle
我爱夜来香A2 小时前
SQL进阶:如何把字段中的键值对转为JSON格式?
数据库·sql·json
micromicrofat2 小时前
mongodb升级、改单节点模式
数据库·mongodb
爱编程的王小美3 小时前
本地MySQL连接hive
数据库·hive·mysql
珹洺3 小时前
数据库系统概论(七)初识SQL与SQL基本概念
数据库·sql