plsql
基本语法结构
declare
-- 声明变量
begin
-- 代码逻辑
exception
--异常处理
end;
变量
声明变量的语法
变量名 类型(长度);
变量赋值的语法
变量:=变量值
例子:
-- 变量声明与赋值
declare
v_price number(10,2); -- 单价
v_usenum number; -- 水费字数
v_usenum2 number(10,2); -- 吨数
v_money number(10,2); --金额
begin
v_price := 2.45; -- 单价赋值
v_usenum := 9213; --水费的字数
v_usenum2 := round(v_usenum/1000,2); -- 吨数
v_money := v_price*v_usenum2; -- 金额
dbms_output.put_line('金额:'||V_money);
end;
-- 输出结果:金额:22.56
**************************************************************************
-- 变量 是数据库中查出来的数据
-- select 列名 into 变量名
declare
v_price number(10,2); -- 单价
v_usenum number; -- 水费字数
v_usenum2 number(10,2); -- 吨数
v_money number(10,2); --金额
v_num0 number; -- 上月水表数
v_num1 number; -- 本月水表数
begin
v_price := 2.45; -- 单价赋值
-- v_usenum := 9213; --水费的字数
--从数据库读取
select usenum,num0,num1 into v_usenum,v_num0,v_num1 from t_account where 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_usenum||' 金额:'||v_money||' num0:'||v_num0||' num1:'||v_num1);
end;
-- 输出结果:水费字数:2104 金额:5.15 num0:15 num1:20
属性类型
-- 属性类型 (引用类型 表名.列名%type)
declare
v_price number(10,2); -- 单价
v_usenum t_account.usenum%type; -- 水费字数
v_usenum2 number(10,2); -- 吨数
v_money number(10,2); --金额
v_num0 t_account.num0%type; -- 上月水表数
v_num1 t_account.num1%type; -- 本月水表数
begin
v_price := 2.45; -- 单价赋值
-- v_usenum := 9213; --水费的字数
select usenum,num0,num1 into v_usenum,v_num0,v_num1 from t_account where 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_usenum||' 金额:'||v_money||' num0:'||v_num0||' num1:'||v_num1);
end;
-------------------------------------------------------
--属性类型 (行记录型 表名%rowtype)
declare
v_price number(10,2); -- 单价
v_usenum2 number(10,2); -- 吨数
v_money number(10,2); --金额
v_account t_account%rowtype; -- 台账行记录类型
-- 相当于java中的实体类 直接通过 表名.列名 调用
begin
v_price := 2.45; -- 单价赋值
-- v_usenum := 9213; --水费的字数
select * into v_account from t_account
where 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_account.usenum||' 金额:'||v_money||' num0:'||v_account.num0||' num1:'||v_account.num1);
end;
异常(例外)
有 预定义异常和用户自定义异常
--语法结构
exception
when 异常类型 then
异常处理
-- no_data_found
declare
v_price number(10,2); -- 单价
v_usenum2 number(10,2); -- 吨数
v_money number(10,2); --金额
v_account t_account%rowtype; -- 台账行记录类型
begin
v_price := 2.45; -- 单价赋值
-- v_usenum := 9213; --水费的字数
select * into v_account from t_account
where year = '2012' and month = '01' and owneruuid = 100;
v_usenum2 := round(v_account.usenum/1000,2); -- 吨数
v_money := v_price*v_usenum2; -- 金额
dbms_output.put_line('水费字数:'||v_account.usenum||' 金额:'||v_money||' num0:'||v_account.num0||' num1:'||v_account.num1);
exception
when no_data_found then
dbms_output.put_line('没有找到数据');
end;
--too_many_rows
declare
v_price number(10,2); -- 单价
v_usenum2 number(10,2); -- 吨数
v_money number(10,2); --金额
v_account t_account%rowtype; -- 台账行记录类型
begin
v_price := 2.45; -- 单价赋值
-- v_usenum := 9213; --水费的字数
select * into v_account from t_account
where year = '2012' and month = '01';
v_usenum2 := round(v_account.usenum/1000,2); -- 吨数
v_money := v_price*v_usenum2; -- 金额
dbms_output.put_line('水费字数:'||v_account.usenum||' 金额:'||v_money||' num0:'||v_account.num0||' num1:'||v_account.num1);
exception
when no_data_found then
dbms_output.put_line('没有找到数据');
when too_many_rows then
dbms_output.put_line('返回多行数据');
end;
条件判断
--基本语法
if 条件 then
业务逻辑
end if;
--相当于
if(){
}
------------------------------------
if 条件 then
业务逻辑
else
业务逻辑
end if;
--相当于
if(){
}else{
}
------------------------------------
if 条件 then
业务逻辑
elsif then
elsif then
else
end if;
-- 相当于
if(){
}else if(){
}else{
}
------------------------------------------------
declare
v_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; -- 台账行记录类型
begin
v_price1 := 2.45; -- 单价赋值(五吨以下)
v_price2 := 3.45; -- 单价赋值(五到十吨)
v_price3 := 4.45; -- 单价赋值(十吨以上)
select * into v_account from t_account
where year = '2012' and month = '01' and owneruuid = 1;
v_usenum2 := round(v_account.usenum/1000,2); -- 吨数
--v_money := v_price*v_usenum2; -- 金额
--阶梯水费计算
if v_usenum2<=5 then
v_money := v_price1*v_usenum2;
elsif v_usenum2>5 and v_usenum2<=10 then
v_money := v_price1*5+v_price2*(v_usenum2-5);
else
v_money := v_price1*5+v_price2*5+v_price3*(v_usenum2-10);
end if;
dbms_output.put_line('水费字数:'||v_account.usenum||' 金额:'||v_money||' num0:'||v_account.num0||' num1:'||v_account.num1);
exception
when no_data_found then
dbms_output.put_line('没有找到数据');
when too_many_rows then
dbms_output.put_line('返回多行数据');
end;
循环
-
无条件循环
--基本语法 loop --循环语句 end loop; ---------------------------------------------------------- --无条件循环:1到100 declare v_num number; begin v_num := 1; loop dbms_output.put_line(v_num); v_num := v_num+1; if v_num>100 then exit; -- loop (无条件循环)中需要写exit跳出循环 相当于java中的return end if; -- exit when v_num>100; -- 也可以不写if then 直接写这个 这种写法效果是一样的 end loop; end;
-
条件循环
--基本语法 while 条件 loop --循环语句 end loop; ----------------------------------------------------------- --有条件循环:1到100 declare v_num number; begin v_num := 1; while v_num<=100 loop dbms_output.put_line(v_num); v_num:=v_num+1; end loop; end; ----------------------------------------------------------- declare v_num number; begin v_num := 1; while v_num<=100 loop dbms_output.put_line(v_num); v_num:=v_num+1; exit when v_num>50 -- 可以手动跳出 end loop; end;
-
for循环
--基本语法 declare -- declare可以不写 begin for 变量 in 1..100 --变量可以不声明 但是这个变量只能在循环着中使用 loop end loop; end;
游标
游标是系统为用户开设的一个数据缓冲区,存放sql语句的执行结果。我们可以把游标理解PL/SQL中的结果集。
基本语法
--在声明区声明游标
cursor 游标名称 is sql语句
--使用游标语法
open 游标名称 --打开游标
loop
fetch 游标名称 into 变量
exit when 游标名称%notfound -- notfound 是游标中的属性 当游标走到底会返回一个true 除此之外还有一个found的属性它返回的值与notfound相反
end loop;
close 游标名称;--关闭游标
不带参数的游标
declare
cursor cur_pricetable is select * from t_account where usenum = '2104';--声明游标
v_pricetable t_account%rowtype;
begin
open cur_pricetable;--打开游标
loop
fetch cur_pricetable into v_pricetable;--提取游标
exit when cur_pricetable%notfound;--退出循环
dbms_output.put_line('ID:'||v_pricetable.OWNERUUID);
end loop;
close cur_pricetable;--关闭游标
end;
带参数的游标
declare
cursor cur_pricetable(v_ownertype varchar2) is select * from t_account where usenum = v_ownertype;
v_pricetable t_account%rowtype;
begin
open cur_pricetable('2104');--打开游标 感觉这个open相当于java里调用方法传参数
loop
fetch cur_pricetable into v_pricetable;--提取游标
exit when cur_pricetable%notfound;--退出循环
dbms_output.put_line('ID:'||v_pricetable.OWNERUUID);
end loop;
close cur_pricetable;--关闭游标
end;
for循环 游标
declare
cursor cur_pricetable(v_ownertype varchar2) is select * from t_account where usenum = v_ownertype;
-- v_pricetable t_account%rowtype; --自动声明 但是只能在循环中使用
begin
for v_pricetable in cur_pricetable('2104') --带参数的
-- for v_pricetable in cur_pricetable --如果不带参数不写就行了
loop
dbms_output.put_line('ID:'||v_pricetable.OWNERUUID);
end loop;
end;
--for循环会自动打开关闭游标 会自动提取游标 变量也会自动声明
存储函数
存储函数又称为自定义函数。可以接收一个或多个参数,返回一个结果。在函数中我们可以使用plsql进行逻辑处理。
存储函数基本语法
create [or replace] function 函数名称
(参数名称 参数类型,参数名称 参数类型,....)
return 结果变量数据类型
is
变量声明部分;
begin
逻辑部分;
return 结果变量;
[exception
异常处理部分]
end;
create or replace function fn_gecaddress
(v_id number)
return varchar2
is
v_name varchar2(30);
begin
select year into v_name from t_account where OWNERUUID = v_id;
return v_name;
end; -- 执行之后在function文件夹中可以看到
-------------------------------------------------------------------------
--自定义存储函数测试
select fn_gecaddress(1) from dual;--通过函数名调用 有参数需要传参
存储过程
存储过程是被命名的pl/ql块,存储于数据库中,是数据库对象的一种,应用程序可以调用存储过程,执行相应的逻辑。
存储过程与存储函数都可以封装一定的业务逻辑并返回结果,存在区别如下:
- 存储函数中有返回值,且必须返回;而存储过程没有返回值,可以通过传出参数返回多个值。
- 存储函数可以在select语句中直接使用,而存储过程不能。过程多数是被应用程序所调用。
- 存储函数一般都是封装一个查询结果,而存储过程一般都橙装一段事务代码。
存储过程基本语法
create [or replace] procedure 存储过程名称
(参数名 类型,参数名 类型,参数名 类型)
is|as
变量声明;
begin
逻辑部分
[exception
异常处理部分]
end;
参数只指定类型,不指定长度
过程参数的三种模式:
IN 传入参数(默认,可以不写)
OUT 传出参数,主要用于返回程序运行结果
IN OUT 传入传出参数
不带传出参数的存储过程
CREATE OR REPLACE procedure pro_owners_add
(
v_id number,
v_usenum number,
v_year varchar2,
v_month varchar2
)
is
begin
insert into t_account values(v_id,v_usenum,v_year,v_month,0,0);
commit;
end;
--调用存储过程
call pro_owners_add(11,22,'ss','kk')
--或者
begin
pro_owners_add(66,77,'qs','dk');
end;
带传出参数的存储过程
CREATE OR REPLACE procedure pro_owners_add
(
v_id number,
v_usenum number,
v_year varchar2,
v_month varchar2,
v_kk out number
)
is
begin
v_kk:=v_id;
insert into t_account values(v_id,v_usenum,v_year,v_month,0,0);
commit;
end;
--调用
declare
v_id number;
begin
pro_owners_add(65,65,'qgs','dgk',v_id);
dbms_output.put_line(v_id);
end;