Oracle基础6

1 存储函数
-- 创建存储函数 fn_getAddressByID,根据 地址ID 查询 地址名称
-- fn_getAddressByID(12) ==> 顺义
-- todo 1.1 获取地址名称的sql
select name from T_ADDRESS where id=1;
-- todo 1.2 创建具有参数的存储函数 并且返回值类型为字符串类型(注意!!这里只写类型不写大小)
--  fn_getAddressByID(addr_id number) return varchar2
create or replace function fn_getAddressByID(addr_id number)
return varchar2
is
    addr_name varchar2(30);
begin
    select name into addr_name from T_ADDRESS where id=addr_id;
    return addr_name;
end;
-- todo 1.3 获取业主id 业主姓名 业主地址名称
-- sql的方式(不使用存储函数)
select
    T_OWNERS.id,
    T_OWNERS.NAME,
    T_ADDRESS.NAME
from
T_OWNERS inner join T_ADDRESS
on T_OWNERS.ADDRESSID=T_ADDRESS.id;
-- 使用存储函数
select T_OWNERS.id,T_OWNERS.name,fn_getAddressByID(T_OWNERS.ADDRESSID)
from T_OWNERS;


-- todo 1.4 练习
-- todo 要求:
-- 创建函数 fn_num_ou()
-- 具有参数 num ==> 整数类型
-- 返回值 ret ==> 字符串类型
-- 功能: 如果参数num为偶数 返回值ret结果为 是
--      如果参数num为偶数 返回值ret结果为 不是
create or replace function fn_num_ou(num number)
return varchar2
is
 ret varchar2(30);
begin
    if mod(num,2)=0 then
        ret := '是';
        return ret;
    else
        ret := '不是';
        return ret;
    end if;
end;

select fn_num_ou('123') from dual;

2 存储过程(传入参数)
-- todo 需求: 使用存储过程 完成 对t_owners表的数据插入
-- todo 2.1 准备工作(t_owners有主键)  创建序列 seq_owners 起始值100 生成主键值
create sequence seq_owners start with 100 increment by 1;
-- todo 2.2 创建传入参数的存储过程 pro_owners_add 添加业主信息 create procedure
--  注意!!!:参数只能写类型不能写大小
create or replace procedure pro_owners_add(
--  参数: v_name in, v_addressid in, v_housenumber in, v_watermeter in, v_ownertypeid in
    v_name varchar2,
    v_addressid number,
    v_housenumber varchar2,
    v_watermeter varchar2,
    -- ADDDATE 为插入时间 不需要用户设定 直接指定为 插入数据时间即可
    v_ownertypeid number
)
is
begin
-- todo 2.3 向t_owners插入数据
    insert into T_OWNERS
    values (seq_owners.nextval,
            v_name,
            v_addressid,
            v_housenumber,
            v_watermeter, sysdate, v_ownertypeid);
-- todo 2.4 提交数据
    commit;
end;
-- todo 2.5 调用存储过程 添加业主信息 call 存储过程(... ...);
call pro_owners_add('盘丝洞01',66,'66','66',66);
-- todo 2.6 练习
-- 创建删除指定id的pro_owners_del存储过程
-- 要求 t_owners表 传入参数
create or replace procedure pro_owners_del(v_id in number)
is
begin
    -- 根据v_id删除数据
    delete from T_OWNERS where id=v_id;
    -- 提交数据
    commit;
end;
--
call PRO_OWNERS_DEL(100);

 

 3 存储过程(传出参数)
-- todo 需求:创建带传出参数pro_owners_add_2存储过程:添加业主信息
--  要求: 传出参数 v_id number类型 out 传出参数, 当添加完一条数据后
--  注意!!!: 参数只写类型不写大小
create or replace procedure pro_owners_add_2(
    v_NAME varchar2,
    v_ADDRESSID number,
    v_HOUSENUMBER varchar2,
    v_WATERMETER varchar2,
    v_OWNERTYPEID number,
    v_id out number
)
is
begin
-- todo 3.1 调用序列下一个值 赋值给 v_id
    select SEQ_OWNERS.nextval into v_id from dual;
-- todo 3.2 插入 insert into
    insert into T_OWNERS
    values(v_id,v_NAME,v_ADDRESSID,v_HOUSENUMBER,v_WATERMETER,sysdate,v_OWNERTYPEID);
-- todo 3.3 提交
    commit;
end;
-- todo 3.4 使用
-- 注意: 这里通过plsql使用 begin end的形式
declare
    v_id number;
begin
    pro_owners_add_2(
        '盘丝洞02',
        77,
        '77',
        '77',
        77,
        v_id
        );
    DBMS_OUTPUT.PUT_LINE('新插入的数据id为:'||v_id);
end;
-- todo 3.5 练习
-- 创建删除指定id的pro_owners_del_2存储过程
-- 要求
-- 1. t_owners表 传入参数v_id in, 传出参数v_name out 字符窜类型
-- 2. 调用pro_owners_del_2时 获取 删除的数据名称name 并显示出来
create or replace procedure pro_owners_del_2(v_id number, v_name out varchar2)
is
begin
    select name into v_name from T_OWNERS where id=v_id;
    delete from T_OWNERS where id=v_id;
    commit;
end;

declare
    v_name varchar2(30);
begin
    pro_owners_del_2(103,v_name);
    DBMS_OUTPUT.PUT_LINE(v_name);
end;

-- todo 需求1: 通过plsql完成阶梯计费
-- 要求: 计算业主类型为1 用水量为12吨 的用户需要付多少水费(T_PRICETABLE)
declare
    -- 1. 声明变量 v_owner_type 并赋值为 1
    --            v_usernum2 并赋值为 12
    --            v_money 并赋值为0
    v_owner_type number := 1;
    v_usernum2 number := 12;
    v_money number(5,2) := 0;
    -- 2. 创建具有参数v_type的游标 cur_pricetable 用来获取t_pricetable中所有数据
    cursor cur_pricetable(v_type number) is
    select * from T_PRICETABLE
    where OWNERTYPEID=v_type order by T_PRICETABLE.MINNUM;
begin
    -- 3. <for loop end loop>方式 使用游标 cur_pricetable
    for i in cur_pricetable(v_owner_type) loop
        if v_usernum2 <= i.maxnum or i.MAXNUM is null then
            v_money := v_money + (v_usernum2 - i.MINNUM) * i.PRICE;
            exit;
        end if;
            v_money := v_money + (i.MAXNUM - i.MINNUM) * i.PRICE;
        end loop;
    -- 4. 输出金额
    DBMS_OUTPUT.PUT_LINE('金额:'||v_money);
end;

-- todo 需求2: 根据需求1创建存储函数 fn_calmoney(v_owner_type业主类型,v_usernum2用水量)
-- todo 注意: !!!返回值,参数只有类型<没有大小>!!!
create or replace function fn_calmoney(
    v_owner_type number,
    v_usernum2 number
)return number
is
    -- 1. 声明变量 v_money 并赋值为0
    v_money number(5,2) := 0;
    -- 2. 创建具有参数v_type的游标 cur_pricetable 用来获取t_pricetable中所有数据
    cursor cur_pricetable(v_type number) is
    select * from T_PRICETABLE
    where OWNERTYPEID=v_type order by T_PRICETABLE.MINNUM;
begin
    -- 3. <for loop end loop>方式 使用游标 cur_pricetable
    for i in cur_pricetable(v_owner_type) loop
        if v_usernum2 <= i.maxnum or i.MAXNUM is null then
            v_money := v_money + (v_usernum2 - i.MINNUM) * i.PRICE;
            exit;
        end if;
            v_money := v_money + (i.MAXNUM - i.MINNUM) * i.PRICE;
        end loop;
    -- 4. 输出金额
    return v_money;
end;
-- 5. 调用函数 select 函数名()
select fn_calmoney(1,12) from dual;

-- todo 需求3: 用存储过程pro_owner_account完成需求 ==> 在新增用户的同时新增账目记录
-- 问题:
-- 1. 两个表的id需要序列
-- 2. 向t_owners表插入数据的时候 插入的时间为 时间类型 ==> t_account需要year month
-- 3. 向t_owners表插入数据的时候 插入的是addressid(地址id) ==> t_account需要areaid(地区id)

-- todo 1 创建序列
create sequence SEQ_OWNERS start with 1000 increment by 100;
create sequence SEQ_ACCOUNT start with 1000 increment by 100;
-- todo 2 创建存储过程pro_owner_account
create or replace procedure pro_owner_account(
    v_NAME varchar2,
    v_ADDRESSID number,
    v_HOUSENUMBER varchar2,
    v_WATERMETER varchar2,
    v_OWNERTYPEID number
)
is
-- todo 3 声明变量 v_year v_month v_area_id v_owner_id
    v_year char(4);
    v_month char(2);
    v_area_id number;
    v_owner_id number;
begin
-- todo 4 给变量v_year v_month赋值
    v_year := to_char(sysdate,'yyyy');
    v_month := to_char(sysdate,'mm');
-- todo 5 给变量v_area_id赋值
    select distinct AREAID into v_area_id from
    T_OWNERS inner join T_ADDRESS
    on T_OWNERS.ADDRESSID=T_ADDRESS.ID where T_OWNERS.ADDRESSID=1;
-- todo 6 通过序列保存t_owners的id值
    select SEQ_OWNERS.nextval into v_owner_id from dual;
-- todo 7 向t_owners表中插入数据
    insert into T_OWNERS
    values(v_owner_id,v_NAME,v_ADDRESSID,v_HOUSENUMBER,v_WATERMETER,SYSDATE,v_OWNERTYPEID);
-- todo 8 向t_account表中插入数据
    insert into T_ACCOUNT
    values(SEQ_ACCOUNT.nextval,v_owner_id,v_OWNERTYPEID,v_area_id,v_year,v_month,0,0,0,null,null,null,null,null,null);
-- todo 9 提交
    commit;
end;

-- todo 10 调用
call pro_owner_account('盘丝洞03',1,'88','88',1);


 

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值