概述:
PL/SQL(Procedural Language/SQL)是一种 Oracle数据库特有的、支持应用开发的语言,是Oracle在标准SQL语言上进行过程性扩展后形成的程序设计语言。
- PL/SQL Oracle 对 SQL 过程化扩展。
- PL/SQL 数据库编程
- 好处:简单、高效、灵活和实用
1、语法
- 基本语法:
-- 基本语法,(declare、exception可省略)
declare
-- 声明,定义变量
begin
-- 代码
exception
--异常处理
end;
- 实例:实例1,定义变量i,并赋值"你好",输出
declare
i varchar2(20);
begin
i := "你好";
dbms_output.put_line("输出内容是:" || i);
end;
2、入门案例
-- PL/SQL 入门练习1:打印“welcome !!!”
begin
dbms_output.put_line("welcome !!!");
end;
-- PL/SQL 入门练习2:定义变量 v_i ,并赋值 “welcome !!!”,再打印变量
-- 变量的类型,一定要支持赋值内容长度
declare
v_i varchar2(40);
begin
v_i := "welcome welcome !!!";
dbms_output.put_line(v_i);
end;
3、赋值+类型
3.1、赋值 into
-
练习1:打印业主名称
-- 练习1:打印业主名称 declare -- 声明变量,用于存放name的值 begin -- 执行查询语句,获得name的值,并赋值变量 -- 打印变量 end;
-
实现
-- 练习1:打印业主名称 declare -- 声明变量,用于存放name的值 v_name varchar2(50); begin -- 执行查询语句,获得name的值,并赋值变量 select name into v_name from t_owners where id = 11; -- 打印变量 dbms_output.put_line(v_name); end;
3.2、变量类型 %type
-
练习2:打印业主名称,声明变量类型
-- 语法 变量名 表名.列名%type; -- 实例 v_name towners.name%type;
-- 练习2:打印业主名称,变量类型 declare -- 声明变量,用于存放name的值 v_name t_owners.name%type; begin -- 执行查询语句,获得name的值,并赋值变量 select name into v_name from t_owners where id = 11; -- 打印变量 dbms_output.put_line(v_name); end;
3.3、变量类型练习
- 练习3:需求:计算台账中编号为1的用户当月用水金额。
- 要求输出:单价、吨数、金额、上月用水量,本月用水量
-- 练习3:需求:计算台账表中编号为1的用户当月用水金额。
---- 要求输出:单价、吨数、金额、上月用水量、本月用水量
declare
v_price number;
--上月累计用水量 t_account.num0%type
v_num0 number;
--本月累计用水量 t_account.num1%type
v_num1 number;
--使用量 t_account.usenum%type
v_usenum number;
--金额
v_money number;
-- 吨数
v_usenum2 number;
begin
-- 单价
v_price := 3.45;
-- 查询数据,获得用水量、金额
select num0,num1,usenum,money into v_num0,v_num1,v_usenum,v_money from t_account where id = 1;
-- 吨数 19920 --> /1000 --> 19.920 --> 19.92
v_usenum2 := round(v_usenum / 1000 , 2 );
-- 打印
dbms_output.put_line("单价" || v_price || "、吨数"|| v_usenum2 ||"、金额"|| v_money ||"、上月用水量"|| v_num0 ||"、本月用水量"|| v_num1);
end;
3.4、变量类型 %rowtype
-
通过 %rowtype 获得某一行的所有类型,相当于一个对象,存放一条记录
-
声明变量
--语法 变量 表名%rowtype; --实例 v_account t_account%rowtype;
-
赋值
-- 单列 select 列名,列名2,... into 变量.列名,变量.列名2,... from 表名; -- 所有 select * into 变量 from 表名;
-
-
实例:重写练习3:使用 %rowtype
-- 重写练习3:使用%rowtype declare -- 单价 v_price number; -- 声明行变量 v_account t_account%rowtype; begin -- 单价 v_price := 3.45; -- 保存一行数 select * into v_account from t_account where id = 1; -- 打印 dbms_output.put_line("单价" || v_price ||"、金额"|| v_account.money ||"、上月用水量"|| v_account.num0 ||"、本月用水量"|| v_account.num1); end;
4、异常
-- 语法
declare
begin
-- 正常代码
-- 异常块
exception
when 异常类型 then
处理
when 异常类型 then
处理
....
end;
-- 常见异常类型:
no_date_found , 没有数据异常,查询结果为null
too_many_rows,太多行,查询结果大于1条
-
练习4:查询台账表,id为1所有信息,并打印部分 -- 正常情况
-- 异常处理 -- 练习4:查询台账表,id为1所有信息,并打印部分 declare v_account t_account%rowtype; begin --查询 select * into v_account from t_account where id = 1; --打印 dbms_output.put_line("上月用水量" || v_account.num0 || "本月用水量" || v_account.num1); -- 异常处理 exception when no_data_found then dbms_output.put_line("没有查询到数据"); when too_many_rows then dbms_output.put_line("查询结果大于1条"); end;
-
练习4:查询台账表,id为1所有信息,并打印部分 -- 异常情况--没有数据
-- 异常处理 -- 练习4:查询台账表,id为1所有信息,并打印部分 declare v_account t_account%rowtype; begin --查询 select * into v_account from t_account where id = 999; --打印 dbms_output.put_line("上月用水量" || v_account.num0 || "本月用水量" || v_account.num1); -- 异常处理 exception when no_data_found then dbms_output.put_line("没有查询到数据"); when too_many_rows then dbms_output.put_line("查询结果大于1条"); end;
-
练习4:查询台账表,id为1所有信息,并打印部分 -- 异常情况--查询多条数据
-- 练习4:查询台账表,id为1所有信息,并打印部分 declare v_account t_account%rowtype; begin --查询 select * into v_account from t_account; --打印 dbms_output.put_line("上月用水量" || v_account.num0 || "本月用水量" || v_account.num1); -- 异常处理 exception when no_data_found then dbms_output.put_line("没有查询到数据"); when too_many_rows then dbms_output.put_line("查询结果大于1条"); end;
5、判断语句 if
-
if 语法
if 条件 then elsif 条件2 then els if 条件3 then ... else end if;
-
实例:设置三个等级的水费 5吨以下2.45元/吨 5吨到10吨部分3.45元/吨 超过10吨部分4.45 ,根据使用水费的量来计算阶梯水费
-- 需求:设置三个等级的水费 5吨以下2.45元/吨 5吨到10吨部分3.45元/吨 ,超过10吨部分4.45 ,根据使用水费的量来计算阶梯水费。 declare -- 定义3个水费价格 v_price1 number; v_price2 number; v_price3 number; -- 台账记录 v_account t_account%rowtype; -- 使用量(吨数) v_usenum2 number; -- 金额 v_money number; begin -- 确定水费价格 v_price1 := 2.45; v_price2 := 3.45; v_price3 := 4.45; -- 查询记录 select * into v_account from t_account where id = 4; -- 计算使用量 v_usenum2 := round(v_account.usenum / 1000 , 2); -- 根据使用量,计算阶梯水费 if v_usenum2 <= 5 then --- 小于5吨 : 使用量 * 2.45 v_money := v_usenum2 * 2.45; elsif v_usenum2 <= 10 then --- 小于10吨: 5 * 2.45 + (使用量 - 5) * 3.45 v_money := 5 * 2.45 + (v_usenum2 - 5) * 3.45; else --- 大于10吨: 5 * 2.45 + 5 * 3.45 + (使用量 - 10) * 4.45 v_money := 5 * 2.45 + 5 * 3.45 + (v_usenum2 - 10) * 4.45; end if; -- 打印水费 dbms_output.put_line(v_money); end;
6、循环
6.1、无条件循环
--语法
loop
-- 代码
-- 结束循环
exit;
end loop;
- 课上:输出从1开始的100个数
--练习:输出从1开始的100个数
declare
v_i int := 1 ;
begin
loop
dbms_output.put_line(v_i);
-- 累加
v_i := v_i + 1;
-- 退出
if v_i > 100 then
exit;
end if;
end loop;
end;
6.2、while循环
--语法
while 条件
loop
--内容
end loop;
- 课上练习:求 1-100和,并打印
-- 练习:求1-100和,并打印
declare
--计数器
v_i int := 1;
--求和变量
v_sum int := 0;
begin
while v_i <= 100
loop
--求和
v_sum := v_sum + v_i;
--累加
v_i := v_i + 1;
end loop;
--打印
dbms_output.put_line(v_sum);
end;
6.3、for循环
-
语法
for 变量 in 起始值..终止值 loop -- 循环体 end loop;
-
练习1:
-- 练习1:打印1--100数 declare v_i int; begin for v_i in 1..100 loop dbms_output.put_line(v_i); end loop; end;
-
练习2:
-- 练习2:求1-100所有偶数的和,并打印 declare -- 计数变量 v_i int; -- 求和变量 v_sum int := 0; begin for v_i in 1..100 loop -- mod() 用于求余 if mod(v_i,2) = 0 then v_sum := v_sum + v_i; end if; end loop; dbms_output.put_line(v_sum); end;
-
练习3:99乘法表
-- 练习3:99乘法表 --- 输出内容,是否换行 declare begin -- 一行输出 dbms_output.put("abc"); -- 换行输出 dbms_output.put_line("123"); end; -------- 普通循环 declare v_i int; begin -- 循环 for v_i in 1..9 loop dbms_output.put_line(v_i); end loop; end; -------- 嵌套循环 declare v_i int; v_j int; begin -- 嵌套循环 for v_i in 1..9 loop -- 内部循环 for v_j in 1..9 loop dbms_output.put_line(v_i || v_j); end loop; end loop; end; -------99乘法表 declare v_i int; v_j int; begin -- 嵌套循环 for v_i in 1..9 loop -- 内部循环 for v_j in 1..v_i loop dbms_output.put(v_j || " * " || v_i || " = " || (v_i * v_j) ); dbms_output.put(" "); end loop; dbms_output.put_line(""); end loop; end;