15 PL-SQL
什么是 PL/SQL
PL/SQL(Procedure Language/SQL)是 Oracle 对 sql 语言的过程化扩展,指 在 SQL 命令语言中增加了过程处理语句(如分支、循环等),使 SQL 语言具有 过程处理能力。把 SQL 语言的数据操纵能力与过程语言的数据处理能力结合起 来,使得 PLSQL 面向过程但比过程语言简单、高效、灵活和实用。
基本语法结构:
[declare--声明变量]
begin--代码逻辑[exception--异常处理]
end;
变量
声明变量的语法:
变量名 类型(长度);
变量赋值的语法:
变量名:=变量值
变量的声明
需求:
声明变量水费单价、水费字数、吨数、金额。
对水费单价、字数、进行赋值 。吨数根据水费字数换算,规则为水费字数除以 1000,并且四舍五入,保留两位小数。计算金额,金额=单价*吨数。
输出单价 、数量和金额。
declare
v_price number(10, 2); --水费单价
v_usenum number; --水费字数
v_usenum2 number(10, 2); --吨数
v_money number(10, 2); --金额beginv_price:=2.45; --水费单价v_usenum:=8012; --字数--字数换为吨数v_usenum2 := round(v_usenum / 2, 2);--计算金额v_money := round(v_price * v_usenum2, 2);dbms_output.put_line('单价:' || v_price || '吨数:' || v_usenum2 || '金额:' || v_money);
end;
Select into 方式 赋值
语法结构:
select 列名 into 变量名 from 表名 where 条件
注意:结果必须是一条记录 ,有多条记录和没有记录都会报错
属性类型
%TYPE 引用型
作用:引用某表某列的字段类型
declarev_price number(10, 2) ;-- 单价v_usenum t_account.usenum%TYPE;--水费字数v_num0 t_account.num0%TYPE;-- 上月字数v_num1 t_account.num1%TYPE;-- 本月字数v_usenum2 number(10, 2);-- 使用吨数v_money number(10, 2); --水费金额
begin--对单价进行赋值v_price := 3.45;select usenum, num0, num1into v_usenum, V_num0, v_num1from t_accountwhere YEAR = '2012'and MONTH = '01'and OWNERUUID = 1;--使用吨数v_usenum2 := round(v_usenum / 1000, 2);--计算金额v_money := v_price * v_usenum2;DBMS_OUTPUT.put_line('单价:' || v_price || '吨数:' || v_usenum2 || '金额:' || v_money || '上月字数:' || v_num0 || '本月字数' ||v_num1);
end;
%ROWTYPE 记录型 ,上例中的例子可以用下面的代码代替
作用: 标识某个表的行记录类型
declarev_price number(10, 2) ;-- 单价
-- v_usenum t_account.usenum%TYPE;--水费字数
-- v_num0 t_account.num0%TYPE;-- 上月字数
-- v_num1 t_account.num1%TYPE;-- 本月字数v_account t_account%ROWTYPE; --代替上面三个v_usenum2 number(10, 2);-- 使用吨数v_money number(10, 2); --水费金额
begin--对单价进行赋值v_price := 3.45;select *--into v_usenum, V_num0, v_num1into v_account --代替上面一行from t_accountwhere YEAR = '2012'and MONTH = '01'and OWNERUUID = 1;--使用吨数v_usenum2 := round(v_account.usenum / 1000, 2);--计算金额v_money := v_price * v_usenum2;DBMS_OUTPUT.put_line('单价:' || v_price || '吨数:' || v_usenum2 || '金额:' || v_money || '上月字数:' || v_account.NUM0 || '本月字数' ||v_account.NUM1);
end;
异常
在运行程序时出现的错误叫做异常 发生异常后,语句将停止执行,控制权转移到 PL/SQL 块的异常处理部分
异常有两种类型:
预定义异常 - 当 PL/SQL 程序违反 Oracle 规则或超越系统限制时隐式引发
Oracle 预定义异常 21 个
用户定义异常 - 用户可以在 PL/SQL 块的声明部分定义异常,自定义的异常通过 RAISE 语句显式引发
语法结构:
exceptionwhen 异常类型 then异常处理逻辑
根据上例中的代码,添加异常处理部分
declarev_price number(10, 2) ;-- 单价
-- v_usenum t_account.usenum%TYPE;--水费字数
-- v_num0 t_account.num0%TYPE;-- 上月字数
-- v_num1 t_account.num1%TYPE;-- 本月字数v_account t_account%ROWTYPE; --代替上面三个v_usenum2 number(10, 2);-- 使用吨数v_money number(10, 2); --水费金额
begin--对单价进行赋值v_price := 3.45;select *--into v_usenum, V_num0, v_num1into v_account --代替上面一行from t_accountwhere YEAR = '2012'and MONTH = '01'and OWNERUUID = 1;--使用吨数v_usenum2 := round(v_account.usenum / 1000, 2);--计算金额v_money := v_price * v_usenum2;DBMS_OUTPUT.put_line('单价:' || v_price || '吨数:' || v_usenum2 || '金额:' || v_money || '上月字数:' || v_account.NUM0 || '本月字数' ||v_account.NUM1);exceptionwhen NO_DATA_FOUND thendbms_output.put_line('未找到数据,请核实');when TOO_MANY_ROWS thendbms_output.put_line('查询条件有误,返回多条信息,请核实');
end;
条件判断
基本语法 1
if 条件 then业务逻辑
end if;
基本语法 2
if 条件 then业务逻辑else业务逻辑
end if;
基本语法 3
if 条件 then业务逻辑
elsif 条件 then业务逻辑
else业务逻辑
end if;
需求:设置三个等级的水费 5 吨以下 2.45 元/吨 5 吨到 10 吨部分 3.45 元/吨 ,超过 10 吨部分 4.45 ,根据使用水费的量来计算阶梯水费。
--条件判断
declarev_price1 number(10, 2); --单价v_price2 number(10, 2);v_price3 number(10, 2);v_usenum2 number(10, 2); --吨数v_money number(10, 2); --金额v_account t_account%rowtype;beginv_price1 := 2.45; --5吨以下v_price2 := 3.45; --(5-10吨)v_price3 := 4.45;--10吨以上--从数据库中提取select * into v_account from t_account where year = '2012' and month = '01' and owneruuid = 1;v_usenum2 := round(v_account.USENUM / 1000, 2);--吨数--阶梯水费计算if v_usenum2 <= 5 thenv_money := v_price1 * v_usenum2;elsif v_usenum2 > 5 and v_usenum2 <= 10 thenv_money := v_price1 * 5 + v_price2 * (v_usenum2 - 5);elsev_money := v_price1 * 5 + v_price2 * 5 + v_price3 * (v_usenum2 - 10);end if;DBMS_OUTPUT.PUT_LINE('字数:' || v_account.USENUM || '金额:' || v_money);exceptionwhen no_data_found thenDBMS_OUTPUT.PUT_LINE('没有找到账务数据');when too_many_rows thenDBMS_OUTPUT.PUT_LINE('返回多行账务数据');
end;
循环
1.无条件循环
语法结构
loop--循环语句
end loop;
范例:输出从1开始的100个数
declarev_num number := 1;
beginloopDBMS_OUTPUT.PUT_LINE(v_num);v_num := v_num + 1;exit when v_num > 100;end loop;
end;
2、条件循环
语法结构
while 条件
loop
end loop;
范例:输出从1开始的100个数
--有条件循环:1 到100
declarev_num number;
beginv_num:=1;while v_num<=100loopdbms_output.put_line(v_num);v_num:=v_num+1; end loop;
end;
3、for循环
基本语法
for 变量 in 起始值..终止值
loop
end loop;
范例:输出从1开始的100个数
declarev_num number := 1;
beginfor v_num in 1..100loopDBMS_OUTPUT.PUT_LINE(v_num);end loop;
end;
游标
游标是系统为用户开设的一个数据缓冲区,存放 SQL 语句的执行结果。我们
可以把游标理解为 PL/SQL 中的结果集。
语法结构及示例
在声明区声明游标,语法如下:
cursor 游标名称 is SQL 语句;
使用游标语法
open 游标名称
loopfetch 游标名称 into 变量exit when 游标名称%notfound
end loop;
close 游标名称
需求:打印业主类型为 1 的价格表
declarev_pricetable t_pricetable%rowtype; --价格行对象cursor cur_pricetable is select * from t_pricetable where ownertypeid=1; --定义游标
beginopen cur_pricetable; --打开游标loopfetch cur_pricetable into v_pricetable; --提取游标到变量exit when cur_pricetable%notfound; --当游标到最后一行下面退出循环DBMS_OUTPUT.PUT_LINE( '价格:' ||v_pricetable.price ||'吨位:'||v_pricetable.minnum||'-'||v_pricetable.maxnum );end loop;close cur_pricetable; --关闭游标
end;
3.带参数的游标
我们的查询语句的条件值有可能是在运行时才能决定的,比如性业主类型,
可能是运行时才可以决定,那如何实现呢?我们接下来学习带参数的游标,修改 上述案例
declare
4.for 循环提取游标值
未完待续
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
