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