PL/SQL(Procedure Language/SQL)
PLSQL是Oracle对sql语言的过程化扩展:
在SQL命令语言中增加了过程处理语句(如分支、循环等),使SQL语言具有过程处理能力。
SQL语言的数据操作能力与过程语言的数据处理能力相结合,使PLSQL面向过程,但比过程语言简单、高效、灵活、实用。
不同数据库的SQL扩展
Oracle:PL/SQL
DB2:SQL/PL
SQL Server:Transac-SQL(T-SQL)
===============================================================
1、PL/SQL操作数据库效率最高
2、继续学习存储过程,存储函数,触发器
第一个程序
--打开输出开关
set serveroutput on
declare
-- 说明部分(变量,光标或者例外)
begin
--程序体
dbms_output.put_line('hello world');
end;
/
===========================目录===============================
1,PL/SQL的程序结构
2,PL/SQL引用型变量和记录型变量
3,PL/SQL中if语句的使用
4,PL/SQL中循环语句的使用
5,PL/SQL中光标
6,PL/SQL例外
7,程序设计方法
================PL/SQL的程序结构===============================
declare
说明部分(变量说明、光标说明、例外说明)
begin
语句序列(DML语句)
exception
例外处理语句
end;
/
定义基本变量
类型:char,varchar2,date,number,boolean,long
举例:var1 char(15);
married boolean := true;
psal number(7,2);
================PL/SQL引用型变量和记录型变量====================
emp_rec emp%rowtype emp_rec是emp的行,数组类型,可以获取EMP的所有字段,加.字段即可。(记录型变量)
pename emp.ename%type 某个字段的类型,只能获取表中的一个字段。(引用型变量)
================PL/SQL中if语句的使用============================
1、if 条件 then 语句1;
语句2;
end if;
2、if 条件 then 语句1;
else 语句2;
end if;
3、if 条件 then 语句1;
elsif 语句 then 语句;
else 语句;
end if;
-- 判断用户从键盘输入的数字
set serveroutput on
accept num prompt '请输入一个数字';
declare
pnum number:=#
begin
if pnum = 0 then dbms_output.put_line('你输入的是0');
elsif pnum = 1 then dbms_output.put_line('你输入的是1');
else dbms_output.put_line('你输入的是其他数字');
end;
/
================PL/SQL中循环语句的使用============================
1.while循环:当循环条件成立时执行循环体,不成立时退出该循环
WHILE total <= 25000 LOOP
...
total := total + salary;
END LOOP;
2.loop循环:当循环条件不成立时执行循环体,成立时退出该循环
Loop
EXIT [when 条件];
...
End loop;
3.for循环:循环是连续的区间时
FOR I IN 1..3 LOOP
语句序列;
END LOOP;
================PL/SQL中光标============================
定义:就是一个结果集(result set)
语法:
CURSOR 光标名[(参数名 数据类型[,参数名 数据类型]...)]
IS SELECT 语句;
例如 cursor c1 is select ename from emp;
实用:
1.打开光标:
open c1;打开光标执行查询
2.关闭光标:
close c1;关闭游标释放资源
3.取一行光标的值:
fetch c1 into pename;取一行到变量中
fetch的作用:1)把当前指针指向的记录返回
2)讲指针指向下一条记录
属性:
%found %notfound
%isopen判断光标是否打开
%rowcount影响的行数
光标数的限制:默认打开最多300个光标
修改光标数限制 alter system set open_cursors=400 scope=both
scopt属性:memory(只该当前实例),spfile(只改参数文件,数据库需要重启),both(两者都改)
实例:
set serveroutput on
declare
cursor cemp is select ename,salary from emp;
pname emp.ename%type;
psal emp.sal%type;
begin
-- 打开光标
open cemp;
loop
-- 取一条记录
fetch cemp into pename,psal;
exit when cemp%notfound
dbms_output.put_line(pname||'的薪水是'||psal);
end loop
-- 关闭光标
close cemp
end
/
实例1:给员工涨工资
set serveroutput on
declare
--定义光标给哪些员工涨工资
cursor cemp is select empno,empjob from emp;
penmno emp.empno%type;
pjob emp.empjob%type;
begin
--打开光标
--把之前涨的工资回退回去
rollback;
open cemp;
loop
fetch cemp into penmno,pjob;
exit when cemp%notfound
-- 判断新员工的职位
if pjob = 'president' then update emp set sal = sal+1000 where empno = pempno;
elsif pjob = 'manager' then update emp set sal=sal +800 where empno = pempno;
else update emp set sal = sal +400 where empno = pempno;
end if;
end loop
close cemp;
commit;
dbms_output.put_line('涨工资完成');
-- 对于oracle,默认的事务隔离级别是read committed
-- 事务的acid:原子性,一致性,隔离性,持久性,
end;
/
eg:
--使用带参数的光标
declare
--定义一个带参数的游标
cursor c_emp(dno number) is select ename from emp where deptno=dno;
p_ename emp.ename%type;
begin
--打开游标时需要参入实参
open c_emp(10);
loop
fetch c_emp into p_ename;
exit when c_emp%notfound;
DBMS_OUTPUT.PUT_LINE(p_ename);
end loop;
close c_emp;
end;
/
=================PL/SQL例外============================
例外是程序设计语言提供的一种功能,用来增强程序的健壮性和容错性
1.No_date_found(没有找到数据)
2.Too_many_rows (select...into语句匹配多个行)
3.Zero_Divide (被零除)
4.Value_error (算术或转换错误) 如:负数在实数范围开平方,abc字符串 转换成 数字123
5.Timeout_on_resource (等待资源时发生超时)比较典型的场景:分布式数据库
--系统例外:no_data_found
declare
pename emp.ename%type;
begin
select ename into pename from emp where empno=222222;
SYS.DBMS_OUTPUT.PUT_LINE(pename);
exception
when no_data_found then sys.dbms_output.put_line('没有对应的记录');
when others then sys.dbms_output.put_line('其它例外');
end;
/
--系统例外:too_many_rows;
declare
pename emp.ename%type;
begin
select ename into pename from emp where deptno=10;
SYS.DBMS_OUTPUT.PUT_LINE(pename);
exception
when no_data_found then sys.dbms_output.put_line('没有对应的记录');
when too_many_rows then sys.dbms_output.put_line('无法将多行记录赋值给一个普通变量');
when others then sys.dbms_output.put_line('其它例外');
end;
/
--系统例外:zero_divide 被0除
declare
pnum number;
begin
pnum:=1/0;
exception
when zero_divide then
sys.dbms_output.put_line('0不能做除数');
sys.dbms_output.put_line('0真的不能做除数');
when others then sys.dbms_output.put_line('其它例外');
end;
/
--系统例外:value_error算术或转换例外
declare
pnum number;
begin
pnum:='abd';
exception
when value_error then
sys.dbms_output.put_line('算术或者转换错误');
when others then sys.dbms_output.put_line('其它例外');
end;
/
--自定义例外:查询50号部门的员工姓名
set serveroutput on
declare
--定义光标
cursor cemp is select ename from emp where deptno=50;
pename emp.ename%type;
--自定义例外
no_emp_data exception;
begin
open cemp;
loop
fetch cemp into pename;
if cemp%notfound then raise no_emp_data;-- 抛出例外
exit when cemp%notfound;
end if;
end loop;
close cemp;-- 关闭光标,oracle自动启动pmon(process monitor)
exception
when no_emp_data then dbms_output.put_line('没有找到员工');
when others then dbms_output.put_line('其他');
end;
/
=====================程序设计方法============================
需求分析->概要设计->详细设计->编码->测试->上线
sql语句
变量:1、初始值是多少2、最终值如何得到