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等异常,避免程序中断。
文档注释: 为自定义函数添加注释,说明用途、参数及返回值。

相关推荐
我科绝伦(Huanhuan Zhou)1 小时前
浅聊达梦数据库物理热备的概念及原理
数据库·oracle
zhz52142 小时前
从PostgreSQL到人大金仓(KingBase)数据库迁移实战:Spring Boot项目完整迁移指南
数据库·spring boot·postgresql
万行2 小时前
点评项目(Redis中间件)&第一部分Redis基础
java·数据库·redis·缓存·中间件
SelectDB2 小时前
Apache Doris 登顶 RTABench —— 实时分析领域的性能王者
数据库·数据分析·开源
用户6279947182622 小时前
南大通用GBase 8a加载常见错误原因
数据库
咸甜适中2 小时前
rust语言(1.88.0)sqlite数据库rusqlite库(0.37.0)学习笔记
数据库·rust·sqlite·rusqlite
Jasonakeke2 小时前
【重学 MySQL】九十二、 MySQL8 密码强度评估与配置指南
android·数据库·mysql
heath ceTide3 小时前
第二章从事件驱动到信号
数据库·系统架构
StarRocks_labs3 小时前
欧洲数字化养殖平台 Herdwatch 借力 Iceberg + StarRocks 提升分析能力
数据库·starrocks·iceberg·湖仓一体架构·herdwatch
TDengine (老段)4 小时前
TDengine IDMP 5 个实测场景让监控变简单
大数据·数据库·物联网·ai·时序数据库·tdengine·涛思数据