1.PL/SQL的定义:
PL/SQL(Procedure Language/SQL)
PLSQL是Oracle对sql语言的过程化扩展
指在SQL命令语言中增加了过程处理语句(如分支、循环等),使SQL语言具有过程处理能力。
把SQL语言的数据操纵能力与过程语言的数据处理能力结合起来,使得PLSQL面向过程但比过程语言简单、高效、灵活和实用。
Plsql(oracle),Transact-sql(SQL server)
2.入门程序-->打印hello world;
set serveroutput on;
--声明变量 如果没有可以不写
declare
-- 开始
begin
dbms_output.put_line('hello world!');
--结束 必须加上分号
end;
/
运行结果:
注意:如果要在屏幕上输出信息,需要将serveroutput开关打开:
3.声明变量
1)方式一:
set serveroutput on;
declare
--声明一般的变量,可以指定初始值,注意要使用:=
vname emp.ename%type;--和数据库中的变量的类型保持一致
vsal number :=0;--声明为number类型
begin
--把查询的结果赋值给变量
select ename,sal into vname,vsal from emp where empno=7839;
--显示结果
dbms_output.put_line(vname||'的薪水是'||vsal);
end;
/
运行结果:
2)方式二
set serveroutput on;
accept empno prompt '请输入员工编号';
declare
--声明记录变量
rec_emp emp%rowtype;
begin
--把查询出来的结果赋值给变量
select * into rec_emp from emp where empno=&empno;
dbms_output.put_line(rec_emp.ename||'的薪水是'|| rec_emp.sal);
end;
/
运行结果:
4.if
set serveroutput on;
accept num prompt '请输入数字';
declare
--定义变量
vnum number;
vstr varchar2(5);
begin
vnum:= #
if vnum>0 then vstr:='正数';
elsif vnum<0 then vstr:='负数';
else vstr:='零';
end if;
dbms_output.put_line(vstr);
end;
/
5.循环
1)循环方式一
set serveroutput on
begin
for i in 1..10
loop
--循环体内容
dbms_output.put_line(i);
end loop;
end;
/
2)循环方式二(这种方式比较常用)
set serveroutput on;
declare
vnum number :=1;--初始化变量
begin
loop
--退出循环的条件
exit when vnum>10;
dbms_output.put_line(vnum);
--加一
vnum:=vnum+1;
end loop;--结束循环
end;
/
3)循环方式三:
set serveroutput on;
declare
vnum number :=1;
begin
--当条件成立,就执行循环体
while vnum<10
loop
dbms_output.put_line(vnum);
--加一
vnum:=vnum+1;
end loop;
end;
/
运行结果:
6.光标
set serveroutput on;
/*要求:显示总员工数和所有员工的姓名和工资
* select ename,sal from emp;
*/
declare
--声明光标
cursor c_emp is select ename,sal from emp;
--定义变量
vcount number;
vname emp.ename%type;
vsal number;
begin
--查询并显示员工总数量
select count(*) into vcount from emp;
dbms_output.put_line('总的员工数为:'||vcount);
--要使用光标就需要打开光标
open c_emp;
--循环
loop
--先取出一行记录
fetch c_emp into vname,vsal;
--指定退出循环的条件
exit when c_emp%notfound;
dbms_output.put_line(vname||'的工资是'||vsal);
end loop;
--关闭光标
close c_emp;
end;
/
运行结果:
注:这里查询的结果和与cmd命令行查询的结果一致
7.光标应用案例:给员工涨工资
set serveroutput on
--要求 :按照员工的工种涨工资,总裁(PRESIDENT) 1000 ,经理(MANAGER)800 其他员工 400
--分析:取出所有员工,每一个员工就行判断,符合什么条件,就涨多少工资
--select empno,empjob from emp;
-- update emp set sal=sal+? where empno=?
declare
--定义一个光标(所有员工的集合)
cursor c_emp is select empno,empjob from emp;
--定义与光标有关的变量
vempno emp.empno%type;
vempjob emp.empjob%type;
begin
open c_emp;
loop
--获取数据
fetch c_emp into vempno,vempjob;
exit when c_emp%notfound;--指定退出循环的条件
--判断是什么情况 就涨多少工资
if vempjob='PRESIDENT' then update emp set sal=sal+1000 where empno=vempno;
elsif vempjob='MANAGER' then update emp set sal=sal+800 where empno=vempno;
else update emp set sal=sal+400 where empno=vempno;
end if;--结束if判断
end loop;
close c_emp;
commit; --提交事务
dbms_output.put_line('执行完毕');
end;
/
运行结果:
8.带参数的光标
set serveroutput on;
--要求:显示10号部门中的总员工数,和每个员工的姓名和工资信息
declare
--定义光标
cursor c_emp(dno number) is select ename,sal from emp where deptno=dno;
--定义与光标相关的变量
vename emp.ename%type;
vsal emp.sal%type;
vdeptno emp.deptno%type;
vcount number;
begin
--获取查询条件
vdeptno :=&input_deptno;
--显示 部门中的总员工数
select count(*) into vcount from emp where deptno=vdeptno;
dbms_output.put_line('总的员工数为:'||vcount);
--打开光标
open c_emp(vdeptno);
loop
fetch c_emp into vename,vsal;
exit when c_emp%notfound;
dbms_output.put_line(vename||'的工资是'||vsal);
end loop;
close c_emp;--关闭光标
end;
/
运行结果:
9.异常
set serveroutput on
declare
vnum number;
begin
vnum:=1/0;
--处理异常
exception
when zero_divide then dbms_output.put_line('异常:被0除');
end;
/
运行结果:
10.自定义异常
set serveroutput on;
--自定义异常
declare
--声明一个异常类型
my_exception exception;
begin
--抛出异常
raise my_exception;
exception
--异常处理
when my_exception then dbms_output.put_line('自定义异常');
end;
/
运行结果: