PL/SQL语法-01

测试数据

--财务表
create table t_account
(
    id        number primary key,
    owneruuid number,
    ownertype number,
    areaid    number,
    year      char(4),
    month     char(2),
    num0      number,
    num1      number,
    usenum    number,
    meteruser number,
    meterdate date,
    money     number(10, 2),
    isfee     char(1),
    feedate   date,
    feeuser   number
);
-- 用水价格表
create table t_pricetable
(
    id          number primary key,
    price       number(10, 2),
    ownertypeid number,
    minnum      number,
    maxnum      number
);
insert into t_pricetable
values (1, 2.45, 1, 0, 5);
insert into t_pricetable
values (2, 3.45, 1, 5, 10);
insert into t_pricetable
values (3, 4.45, 1, 10, null);

insert into t_pricetable
values (4, 3.87, 2, 0, 5);
insert into t_pricetable
values (5, 4.87, 2, 5, 10);
insert into t_pricetable
values (6, 5.87, 2, 10, null);

insert into t_pricetable
values (7, 4.36, 3, 0, 5);
insert into t_pricetable
values (8, 5.36, 3, 5, 10);
insert into t_pricetable
values (9, 6.36, 3, 10, null);
insert into t_account
values (seq_account.nextval, 1, 1, 1, '2012', '01', 30203, 50123, 0, 1, sysdate, 34.51, '1',
        to_date('2012-02-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 1, 1, 1, '2012', '02', 50123, 60303, 0, 1, sysdate, 23.43, '1',
        to_date('2012-03-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 1, 1, 1, '2012', '03', 60303, 74111, 0, 1, sysdate, 45.34, '1',
        to_date('2012-04-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 1, 1, 1, '2012', '04', 74111, 77012, 0, 1, sysdate, 52.54, '1',
        to_date('2012-05-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 1, 1, 1, '2012', '05', 77012, 79031, 0, 1, sysdate, 54.66, '1',
        to_date('2012-06-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 1, 1, 1, '2012', '06', 79031, 80201, 0, 1, sysdate, 76.45, '1',
        to_date('2012-07-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 1, 1, 1, '2012', '07', 80201, 88331, 0, 1, sysdate, 65.65, '1',
        to_date('2012-08-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 1, 1, 1, '2012', '08', 88331, 89123, 0, 1, sysdate, 55.67, '1',
        to_date('2012-09-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 1, 1, 1, '2012', '09', 89123, 90122, 0, 1, sysdate, 112.54, '1',
        to_date('2012-10-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 1, 1, 1, '2012', '10', 90122, 93911, 0, 1, sysdate, 76.21, '1',
        to_date('2012-11-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 1, 1, 1, '2012', '11', 93911, 95012, 0, 1, sysdate, 76.25, '1',
        to_date('2012-12-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 1, 1, 1, '2012', '12', 95012, 99081, 0, 1, sysdate, 44.51, '1',
        to_date('2013-01-14', 'yyyy-MM-dd'), 2);

insert into t_account
values (seq_account.nextval, 2, 1, 3, '2012', '01', 30334, 50433, 0, 1, sysdate, 34.51, '1',
        to_date('2013-02-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 2, 1, 3, '2012', '02', 50433, 60765, 0, 1, sysdate, 23.43, '1',
        to_date('2013-03-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 2, 1, 3, '2012', '03', 60765, 74155, 0, 1, sysdate, 45.34, '1',
        to_date('2013-04-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 2, 1, 3, '2012', '04', 74155, 77099, 0, 1, sysdate, 52.54, '1',
        to_date('2013-05-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 2, 1, 3, '2012', '05', 77099, 79076, 0, 1, sysdate, 54.66, '1',
        to_date('2013-06-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 2, 1, 3, '2012', '06', 79076, 80287, 0, 1, sysdate, 76.45, '1',
        to_date('2013-07-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 2, 1, 3, '2012', '07', 80287, 88432, 0, 1, sysdate, 65.65, '1',
        to_date('2013-08-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 2, 1, 3, '2012', '08', 88432, 89765, 0, 1, sysdate, 55.67, '1',
        to_date('2013-09-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 2, 1, 3, '2012', '09', 89765, 90567, 0, 1, sysdate, 112.54, '1',
        to_date('2013-10-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 2, 1, 3, '2012', '10', 90567, 93932, 0, 1, sysdate, 76.21, '1',
        to_date('2013-11-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 2, 1, 3, '2012', '11', 93932, 95076, 0, 1, sysdate, 76.25, '1',
        to_date('2013-12-14', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 2, 1, 3, '2012', '12', 95076, 99324, 0, 1, sysdate, 44.51, '1',
        to_date('2014-01-14', 'yyyy-MM-dd'), 2);

insert into t_account
values (seq_account.nextval, 100, 1, 3, '2012', '12', 95076, 99324, 0, 1, sysdate, 44.51, '1',
        to_date('2014-01-01', 'yyyy-MM-dd'), 2);
insert into t_account
values (seq_account.nextval, 101, 1, 3, '2012', '12', 95076, 99324, 0, 1, sysdate, 44.51, '1',
        to_date('2015-01-01', 'yyyy-MM-dd'), 2);

一.变量的使用

1.定义变量及赋值

-- todo 1 变量的基本用法(根据提示 计算水费)
-- 声明变量水费单价 v_price、水费字数 v_usenum、吨数 v_usenum2、金额 v_money。
-- 对水费单价=2.24、字数=8012、进行赋值
-- 吨数根据水费字数换算,规则为水费字数除以1000,并且四舍五入,保留两位小数。
-- 计算金额,金额=单价*吨数。
-- 输出单价 、吨数和金额。
-- DBMS_OUTPUT.PUT_LINE('')
declare
    v_price number(5,2);
    v_usernum number;
    v_usernum2 number(5,2);
    v_money number;
    begin
   v_price :=2.24 ;
   v_usernum := 8012;
   v_usernum2 :=round(v_usernum/1000,2);
   v_money := v_usernum2 * v_price;
   DBMS_OUTPUT.PUT_LINE('单价'||v_price||'吨数'||v_usernum2||'金额'||v_money);
end;
-- todo 2 <select 表字段 into 变量 from 表> 方式赋值
--声明变量: v_price单价,v_usenum水费字数,v_num0上月字数,v_num1本月字数
--        v_usenum2 使用吨数, v_money 水费金额
--单价赋值=3.45
--使用 select 表字段 into 变量 from 表(注意只能有一行数据)
--给 水费字数, 上月字数, 本月字数 赋值
--获取使用水量
--求吨数
--计算应付金额 = 吨数 * 单价
--输出 单价 吨数 应付金额 上月字数 本月字数
declare
    v_price number(5,2);
    v_usernum number;
    v_num0 T_account.num0%type;
    v_num1 T_account.num1%type;
    v_usenum2 number(5,2);
    v_money number(5,2);
    begin
    v_price := 3.45;
    select num0,num1  into v_num0,v_num1 from T_ACCOUNT where id=1;
    --获取使用水量

    v_usernum := v_num1 - v_num0;
    --求吨数
    v_usenum2 := round(v_usernum/1000);
    v_money := v_price*v_usenum2;
    DBMS_OUTPUT.PUT_LINE('单价:'||v_price||'吨数:'||v_usenum2||'金额'||v_money);
end;

2.行变量的使用

-- 表%rowtype 引用表中所有字段的类型
-- 注意: 行变量必须获取一行的完整数据
declare
    v_usenum number;
    v_usenum2 number(5,2);
    v_money number(5,2);
    v_price number(5,2);
    v_account  T_account%rowtype;
    begin
    select * into v_account from T_ACCOUNT where id=1;
    v_price:=2.24;
    v_usenum :=v_account.NUM1 - v_account.NUM0;
    v_usenum2 := round(v_usenum/1000);
    v_money := v_price*v_usenum2;
    DBMS_OUTPUT.PUT_LINE('单价:'||v_price||'吨数:'||v_usenum2||'金额'||v_money);
end;

二.异常的处理

-- todo 3 异常处理
-- 异常处理的语法
-- exception
--     when 错误类型 then
--         处理异常;
-- todo 1.1 按照步骤完成要求
declare
    v_usenum2 number(5,2);
    v_money number(5,2);
    v_price number(5,2);
    v_usenum number;
    -- 表中的所有字段都可以存储到这个变量里
    -- !!!一行数据!!!
    v_account T_ACCOUNT%rowtype;
begin
    -- 单价
    v_price := 2.24;
    -- 行变量赋值
    select * into v_account from T_ACCOUNT
--     where id=1; -- 正常的
--     where year=2012; -- 数据行数太多了
    where id=1000; -- 数据找不到
    -- 使用水量
    v_usenum := v_account.NUM1 -v_account.NUM0;
    -- 吨数
    v_usenum2 := round(v_usenum/1000,2);
    -- 金额
    v_money := v_usenum2 * v_price;
    DBMS_OUTPUT.PUT_LINE('单价:'||v_price||' 吨数:'||v_usenum2||' 金额:'||v_money);
    -- todo 处理异常 exception
    exception
        -- 处理 未找到数据异常 no_data_found when then
        when no_data_found then
            DBMS_OUTPUT.PUT_LINE('数据找不到!!!');
        when too_many_rows then
            DBMS_OUTPUT.PUT_LINE('数据太多!!!');
        when others then
            DBMS_OUTPUT.PUT_LINE('异常:'||sqlcode||sqlerrm);
            -- 其他异常 others
            --  sqlcode错误代码
            --  sqlerrm错误信息
end;

三.条件语句

-- todo 6 目标: 使用判断if计算阶梯水费
-- 语法:
-- if 条件 then
--   业务逻辑
-- elsif 条件 then
--   业务逻辑
-- else
--   业务逻辑
-- end if;
-- todo 业务: 设置三个等级的水费
--  5 吨以下           2.45  元/吨,
--  5 吨到 10 吨部分   3.45  元/吨,
--  超过 10 吨部分     4.45  元/吨,
--  根据使用水费的量来计算阶梯水费
declare
    -- 声明变量:
    -- v_price1 <5吨单价
    v_price1 number(5,2);
    -- v_price2 [5,10)吨单价
    v_price2 number(5,2);
    -- v_price3 >=10吨单价
    v_price3 number(5,2);

    -- v_account 行变量
    v_account T_ACCOUNT%rowtype;
    -- v_usenum2 使用吨数
    v_usenum2 number(5,2);
    -- v_money 水费金额
    v_money number(5,2);
begin
    -- 单价赋值: <5吨单价=2.45,  [5,10)吨单价=3.45, >=10吨单价=4.45
    v_price1 := 2.45;
    v_price2 := 3.45;
    v_price3 := 4.45;
    -- 使用 select into 给 行变量 赋值
    select * into v_account from T_ACCOUNT where id=1;
    -- 求吨数
    v_usenum2 := round(v_account.USENUM/1000,2);
    -- 计算阶梯水费 通过判断
    if v_usenum2>=0 and v_usenum2 <= 5 then
        v_money := v_usenum2 * v_price1;
    elsif v_usenum2>5 and v_usenum2<=10 then
        v_money := (5 * v_price1) + (v_usenum2-5) * v_price2;
    else
        v_money := (5 * v_price1) + (5 * v_price2) + (v_usenum2-10)*v_price3;
    end if;
    -- 输出 吨数 应付金额
    DBMS_OUTPUT.PUT_LINE('金额: '||v_money);
end;

四.循环语句

declare
    -- 使用 loop 输出 1 ~ 100
    -- 定义变量 v_num
    v_num number;
begin
    -- 赋值 v_num等于1
    v_num := 1;
    -- 编写 loop 循环
    loop
    -- 进入循环, 输出 v_num变量的值
        DBMS_OUTPUT.PUT_LINE('数字: '||v_num);
    -- 变量 v_num 加 1
        v_num := v_num + 1;
    -- 当 exit when v_num>100时退出
        exit when v_num>100;
    end loop;
end;


-- while循环
-- while 条件
-- loop
--   业务逻辑
-- end loop;
declare
-- 使用 while 输出 1 ~ 100
-- 初始化变量 v_num等于1
    v_num number := 1;
begin
-- 编写 while 循环, 指定继续执行条件 v_num<=100
    while v_num<=100
    loop
-- 进入循环, 输出 v_num变量的值
       DBMS_OUTPUT.PUT_LINE('数字: '||v_num);
-- 变量 v_num 加 1
       v_num := v_num + 1;
    end loop;
end;


-- for循环
-- 语法:
-- for 变量  in 起始值..终止值
-- loop
--   业务逻辑
-- end loop;
declare
begin
    for i in 1..100
    loop
        DBMS_OUTPUT.PUT_LINE('数字: '||i);
    end loop;
end;

五.游标的使用

1.基础用法

-- todo 10 不带参数的游标
-- 创建游标语法:
-- cursor  游标名称  is   SQL语句;
-- 使用游标语法:
-- open 游标名称
-- loop
--   业务逻辑
-- fetch 游标名称  into 变量
-- exit   when   游标名称%notfound
--   业务逻辑
-- end loop;
-- close 游标名称

-- todo 需求:打印业主类型为 1 的价格表 显示如下
-- 价格: 2.45, 吨位: 0--5
-- 价格: 3.45, 吨位: 5--10
-- 价格: 4.45, 吨位: 10--
declare
-- todo 1 声明行变量 v_pricetable
    v_pricetable T_PRICETABLE%rowtype;
-- todo 2 声明游标 cur_pricetable 保存业主类型为 1 的价格表 <cursor 游标名称 is SQL语句;>
    cursor cur_pricetable(c_id number) is
    select * from T_PRICETABLE where OWNERTYPEID=c_id;
begin
-- todo 3 打开游标
    open cur_pricetable(1);
-- todo 4 loop 循环
    loop
-- todo 5 fetch 游标 into 变量 提取游标到变量
        fetch cur_pricetable into v_pricetable;
-- todo 7 当游标到最后一行下面退出循环 exit when 游标%notfound;
        exit when cur_pricetable%notfound;
-- todo 6 输出 价格: XX, 吨位: YY-ZZ
        DBMS_OUTPUT.PUT_LINE('价格: '||v_pricetable.PRICE||'吨位:'||v_pricetable.MINNUM||'--'||v_pricetable.MAXNUM);
    end loop;
-- todo 8 关闭游标
    close cur_pricetable;
end;

2.配合for循环的简化用法(常用)

-- todo 需求:使用for 打印根据参数值显示指定业主类型 的 价格表
declare
    -- 创建游标
    cursor cur_a(o_type number) is
    select * from T_PRICETABLE where OWNERTYPEID=o_type;
begin
    -- for显示游标中的数据
    for i in cur_a(1) loop
     DBMS_OUTPUT.PUT_LINE('价格:'||i.PRICE||', 吨位:'||i.MINNUM||'--'||i.MAXNUM);
     end loop;
end;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值