PL/SQL

什么是PL/SQL
PL/SQL是一种过程语言,通过增加编程语言的特点,实现对SQL的扩展
PL/SQL的特点
支持所有SQL的语法
支持case语句
通过继承,实现子类具有父类的属性和方法
设置了新的日期类型

PL/SQL工作原理
PL/SQL
PL/SQL
PL/SQL语句块
PL/SQL
PL/SQL
命名规则
变量名首字母必须是英文字母,其后可以是字母、数字或者特殊字符 $、#、_等
变量名长度不超过30个字符
变量名中不能有空格
例:
PL/SQL
PL/SQL
表达式的分类
数值型
字符型
日期型
布尔型
运算符分类
算术运算符
关系运算符
逻辑运算符
其他运算符

流程控制
if 语句
PL/SQL
PL/SQL
例:
--计数器,当数字是10时,停止计数
set serveroutput on;
declare
count_v number :=1;
begin
loop
if count_v>=10
then exit;
ELSE
count_v:=count_v+1;
end if;
end loop;
dbms_output.put_line(count_v);
end;

case 语句:一句variable表达式,选择相应的when子句执行
PL/SQL
PL/SQL
例:
set serveroutput on;--开启输出台服务
declare
result_v VARCHAR2(20) :='G';--评分结果
remark_v VARCHAR2(20); --评价
BEGIN
case result_v
when 'A' then remark_v :='甲';
when 'B' then remark_v :='乙';
when 'C' then remark_v :='丙';
when 'D' then remark_v :='丁';
else remark_v :='成绩非常差';
end case;
dbms_output.put_line(remark_v);--在输出台输出信息
end;


循环结构
while-loop循环
PL/SQL
PL/SQL
例:
--计数器:当数字是10时,停止计数
set serveroutput on;
declare
count_v number :=1;
begin
while count_v<10
loop
count_v:=count_v+1;
end loop;
dbms_output.put_line(count_v);
end;

for-loop循环
PL/SQL
PL/SQL
--计数器:当数字是10时,停止计数
例:
set serveroutput on;
declare
count_v number :=1;
begin
for count_v in 1..10
loop
dbms_output.put_line(count_v);
end loop;
end;

PL/SQL的预定义异常
PL/SQL
PL/SQL

PL/SQL中的异常处理
使用RAISE关键字引发异常处理
使用EXCEPTION关键字处理异常
PL/SQL
PL/SQL
例:
set serveroutput on;
declare
score VARCHAR2(10) :='B';
begin
case score
when 'A' then dbms_output.put_line('优秀');
end case;
exception
when OTHERS
then dbms_output.put_line('没有选项');
end;
例:
set serveroutput on;
declare
number_v number:=11;
test_exception exception;-- 声明异常
begin
case number_v
when 10
then raise test_exception;--抛出异常
else
dbms_output.put_line(number_v);
end case;
exception
when test_exception
then dbms_output.put_line('抛出异常');
end;
例:
--判断今天是周几
set serveroutput on;
declare
week varchar2(10);
begin
select to_char(sysdate,'D') into week from dual;
case week
when 2 then
week:='周一';
when 3 then
week:='周二';
when 4 then
week:='周三';
when 5 then
week:='周四';
when 6 then
week:='周五';
when 7 then
week:='周六';
ELSE
week :='周天';
end case;
dbms_output.put_line(week);
end;

常用的变量类型:
PL/SQL
PL/SQL

复杂变量:
PL/SQL
PL/SQL
例:
set serveroutput on;
--type 声明的是数据类型
--is table of 固定写法:一组什么类型的集合
--is table of number 一组数字类型的集合
--is table of varchar2(20) 一组可变长度的字符串的集合
--index 代表下标
--index by 下标的类型
--index by binary_integer代表下标类型是整数型
declare type number_set is table of varchar2(20) index by binary_integer;
my_number number_set;
begin
my_number(1):='abc';
dbms_output.put_line(my_number(1));
end;

例:
--record是类 类型
--包含多个属性
-- is record固定语法
set serveroutput on;
declare type type_a is record(id_v temp_user.id%type,name_v temp_user.name%type);
test_a type_a;
begin
test_a.id_v:=1;
test_a.name_v:='abc';
dbms_output.put_line(test_a.id_v||test_a.name_v);
end;

例:
set serveroutput on;
declare
type t_user is record(id_v temp_user.id%type,name_v temp_user.name%type);
type t_set is table of t_user index by binary_integer;
users t_set;
num binary_integer;
begin
for num in 1..10
loop
users(num).id_v:=num;
users(num).name_v:='葫芦娃'||num;
end loop;
dbms_output.put_line(users(10).name_v);
end;

例:
set serveroutput on;
declare
--type t_user temp_user%rowtype;错误的
type t_set is table of temp_user%rowtype index by binary_integer;
users t_set;
num binary_integer;
begin
for num in 1..10
loop
users(num).id:=num;
users(num).name:='葫芦娃'||num;
end loop;
dbms_output.put_line(users(10).name);
end;


课后小练习:
模拟实时转账 从张三的账户转账1000元到李四的账户

方法1:
set serveroutput on;
declare
zhangsan bank_acount%rowtype;
lisi bank_acount%rowtype;
begin
select * into zhangsan from bank_acount where cardno='1001001';
select * into lisi from bank_acount where cardno='1001002';
dbms_output.put_line('张三编号:'||zhangsan.cardno||',原来的金额:'||zhangsan.money||',李四编号:'||lisi.cardno||',原来的金额:'||lisi.money);
--转账
UPDATE bank_acount set money=money-1000 where cardno='1001001';
UPDATE bank_acount set money=money+1000 where cardno='1001002';
COMMIT;
select * into zhangsan from bank_acount where cardno='1001001';
select * into lisi from bank_acount where cardno='1001002';
dbms_output.put_line('张三编号:'||zhangsan.cardno||',现在的金额:'||zhangsan.money||',李四编号:'||lisi.cardno||',现在的金额:'||lisi.money);
exception
when OTHERS then rollback;
end;

方法2:
set serveroutput on;
declare
zhangsan bank_acount%rowtype;
lisi bank_acount%rowtype;
begin
select * into zhangsan from bank_acount where cardno='1001001';
select * into lisi from bank_acount where cardno='1001002';
dbms_output.put_line('张三编号:'||zhangsan.cardno||',原来的金额:'||zhangsan.money||',李四编号:'||lisi.cardno||',原来的金额:'||lisi.money);
--转账
UPDATE bank_acount set money=money-1000 where cardno='1001001';
UPDATE bank_acount set money=money+1000 where cardno='1001002';
COMMIT;
select * into zhangsan from bank_acount where cardno='1001001';
select * into lisi from bank_acount where cardno='1001002';
dbms_output.put_line('张三编号:'||zhangsan.cardno||',现在的金额:'||zhangsan.money||',李四编号:'||lisi.cardno||',现在的金额:'||lisi.money);
exception
when OTHERS then rollback;
end;