PL/SQL 基础详解
PL/SQL(Procedural Language for SQL)是 Oracle 数据库中的一种过程式语言,它扩展了 SQL 的功能,允许开发者编写复杂的程序逻辑。
一、匿名块
解释
匿名块是 PL/SQL 的基本执行单位,它是一段独立的 PL/SQL 代码,没有名称,不能被其他程序调用,主要用于测试和临时操作。
语法格式
[DECLARE]-- 声明变量、游标等
BEGIN-- 执行 SQL 语句和 PL/SQL 代码
EXCEPTION-- 处理异常
END;
使用
DECLAREnum NUMBER := 10;
BEGINDBMS_OUTPUT.PUT_LINE('num = ' || num);
END;
二、存储过程
解释
存储过程是一组为了完成特定功能的 SQL 语句集,经编译后存储在数据库中,可以通过名称调用执行。
语法格式
CREATE [OR REPLACE] PROCEDURE 过程名 (参数列表)
IS-- 声明部分
BEGIN-- 执行部分
EXCEPTION-- 异常处理部分
END;
使用
CREATE OR REPLACE PROCEDURE add_proc (a IN NUMBER, b IN NUMBER, c OUT NUMBER)
IS
BEGINc := a + b;
END;
三、函数
解释
函数与存储过程类似,但函数必须返回一个值,通常用于计算并返回结果。
语法格式
CREATE [OR REPLACE] FUNCTION 函数名 (参数列表)
RETURN 返回类型
IS-- 声明部分
BEGIN-- 执行部分RETURN 返回值;
EXCEPTION-- 异常处理部分
END;
使用
CREATE OR REPLACE FUNCTION max_proc (a IN NUMBER, b IN NUMBER)
RETURN NUMBER
IS
BEGINIF a > b THENRETURN a;ELSERETURN b;END IF;
END;
四、触发器
解释
触发器是当对表进行某种操作(如 INSERT、UPDATE、DELETE)时自动执行的 PL/SQL 程序。
语法格式
CREATE [OR REPLACE] TRIGGER 触发器名
{BEFORE | AFTER} 触发事件
ON 表名
[FOR EACH ROW]
DECLARE-- 声明部分
BEGIN-- 执行部分
END;
使用
CREATE OR REPLACE TRIGGER update_trigger
AFTER UPDATE ON employees
FOR EACH ROW
BEGINDBMS_OUTPUT.PUT_LINE('员工信息已更新');
END;
五、变量声明和数据类型
解释
在 PL/SQL 中,可以在 DECLARE 部分声明变量,并为其指定数据类型,用于存储临时数据。
语法格式
DECLARE变量名 数据类型;
使用
DECLAREnum NUMBER(5);name VARCHAR2(20);hiredate DATE;
BEGINnum := 100;name := '张三';hiredate := SYSDATE;
END;
六、条件语句
解释
条件语句用于根据不同的条件执行不同的代码块,实现分支逻辑。
语法格式
IF 条件 THEN-- 语句块 1
ELSIF 条件 THEN-- 语句块 2
ELSE-- 语句块 3
END IF;
使用
DECLAREnum NUMBER := 60;
BEGINIF num >= 60 THENDBMS_OUTPUT.PUT_LINE('及格');ELSEDBMS_OUTPUT.PUT_LINE('不及格');END IF;
END;
七、循环语句
解释
循环语句用于重复执行一段代码,直到满足特定条件为止。
语法格式
-- 基本循环
LOOP-- 语句块EXIT WHEN 条件;
END LOOP;-- WHILE 循环
WHILE 条件 LOOP-- 语句块
END LOOP;-- FOR 循环
FOR 循环变量 IN 范围 LOOP-- 语句块
END LOOP;
使用
DECLAREnum NUMBER := 1;
BEGINWHILE num <= 5 LOOPDBMS_OUTPUT.PUT_LINE(num);num := num + 1;END LOOP;
END;
八、游标
解释
游标用于处理 SELECT 语句返回的多行记录,允许逐行处理查询结果。
语法格式
-- 声明游标
CURSOR 游标名 ISSELECT 语句;-- 打开游标
OPEN 游标名;-- 提取数据
FETCH 游标名 INTO 变量;-- 关闭游标
CLOSE 游标名;
使用
DECLARECURSOR emp_cursor ISSELECT employee_id, last_name FROM employees;emp_record emp_cursor%ROWTYPE;
BEGINOPEN emp_cursor;LOOPFETCH emp_cursor INTO emp_record;EXIT WHEN emp_cursor%NOTFOUND;DBMS_OUTPUT.PUT_LINE(emp_record.employee_id || ' ' || emp_record.last_name);END LOOP;CLOSE emp_cursor;
END;
九、异常处理
解释
异常处理用于处理程序运行时出现的错误,确保程序的健壮性和稳定性。
语法格式
BEGIN-- 代码
EXCEPTIONWHEN 异常名 THEN-- 处理代码WHEN OTHERS THEN-- 处理代码
END;
使用
DECLAREnum NUMBER := 0;
BEGINIF num = 0 THENRAISE DIVIDE_BY_ZERO;END IF;
EXCEPTIONWHEN DIVIDE_BY_ZERO THENDBMS_OUTPUT.PUT_LINE('除数不能为零');
END;
十、内置函数
解释
PL/SQL 提供了丰富的内置函数,用于处理字符串、数值、日期等数据类型。
语法格式
函数名(参数);
使用
DECLAREstr VARCHAR2(20) := 'Hello, World!';
BEGINDBMS_OUTPUT.PUT_LINE(LENGTH(str)); -- 计算字符串长度DBMS_OUTPUT.PUT_LINE(UPPER(str)); -- 将字符串转换为大写
END;
十一、存储过程和函数的调用
解释
存储过程和函数可以通过特定的语法进行调用,以执行其内部的逻辑。
语法格式
-- 调用存储过程
EXECUTE 存储过程名(参数);-- 调用函数
函数名(参数);
使用
-- 调用存储过程
EXECUTE add_proc(10, 20, :result);-- 调用函数
DECLAREmax_num NUMBER;
BEGINmax_num := max_proc(10, 20);DBMS_OUTPUT.PUT_LINE('最大值为:' || max_num);
END;