从plsql到存储过程(入门)

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;
循环
  1. 无条件循环

    --基本语法
    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;
    
    
  2. 条件循环

    --基本语法 
    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;
    
  3. 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块,存储于数据库中,是数据库对象的一种,应用程序可以调用存储过程,执行相应的逻辑。

存储过程与存储函数都可以封装一定的业务逻辑并返回结果,存在区别如下:

  1. 存储函数中有返回值,且必须返回;而存储过程没有返回值,可以通过传出参数返回多个值。
  2. 存储函数可以在select语句中直接使用,而存储过程不能。过程多数是被应用程序所调用。
  3. 存储函数一般都是封装一个查询结果,而存储过程一般都橙装一段事务代码。
存储过程基本语法
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;

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 很抱歉,我是一名AI语言模型,无法提供完整的书籍或课程。但是,我可以为您提供一些学习Oracle PL/SQL的建议: 1. 先学习SQL语言基础,掌握基本的查询、过滤、排序等操作。 2. 学习PL/SQL语言基础,包括变量、条件语句、循环语句、函数、存储过程等。 3. 熟悉Oracle数据库的基本操作,包括表的创建、修改、删除等。 4. 学习Oracle PL/SQL的高级特性,如游标、触发器、异常处理等。 5. 练习实战,通过编写实际的PL/SQL程序来提高自己的技能。 6. 参考相关的书籍、教程、博客等资源,不断学习和提高。 希望这些建议能够对您有所帮助。 ### 回答2: Oracle PL/SQL是一种流行的关系数据库管理系统,它具有强大的编程能力和用户友好的特性。想要从入门到精通这个工具,还需要经过以下步骤: 1.了解编程语言:PL/SQL是与SQL紧密相关的编程语言。了解SQL和PL/SQL的基础知识,掌握基本的变量、数据类型、语句和流程控制构造。 2.学习PL/SQL的结构和特性:PL/SQL包含包、过程、函数和触发器,我们需要学习每个结构的定义和用途。 3.掌握代码结构和正确的命名约定:建立一种整洁且易于维护的程序结构和符合行业标准的命名约定。这可以帮助程序员快速查找和修复错误,并且能够与其他程序员之间更好的协作。 4.处理异常:PL/SQL允许开发人员的捕获异常的情况,这是尽可能让代码稳定的一种方法。处理异常的能力是进一步提高PL/SQL代码质量的基础。 5.深入学习行标准库:Oracle PL/SQL有很多用于操作数据库对象的函数和过程,例如包含如存储过程和特定的函数。深入了解这些库,可以极大地提高开发效率,加快开发进程。 6.编写并调试效率高的代码:从代码复杂度到效率和可读性方面考虑,去评估现有代码,并帮助提高代码的故障排查速度。 7.学习动态PL/SQL:动态PL/SQL是替换硬编码变量的一种替代方案,允许改进程序的动态性。当您发现需要编写更灵活的代码,动态PL/SQL就可以解决这个问题。 总之,学习Oracle PL/SQL需要您从其基础知识和函数库入口开始。一方面,熟悉这些基础知识将有助于您了解如何使用PL/SQL来控制数据库。另一方面,深入学习函数库可以从编程的角度洞察PL / SQL语言的工作机制。随着您掌握更多的特性和用例,您就可以逐步提高自己的PL/SQL组成技能,以提高数据库技术水平。 ### 回答3: Oracle PL/SQL是Oracle数据库的编程语言,它结合了SQL语言的数据操纵能力和程序语言的控制结构。这种语言允许用户编写存储过程、触发器、函数和包,这些对象可以在Oracle数据库服务器中存储和执行。Oracle PL/SQL语言的学习可以大大提高数据库开发和管理的效率和安全性。 从入门到精通Oracle PL/SQL,需要掌握一些必要的基本知识: 1. SQL语言: PL/SQL必不可少的一部分就是SQL语言。必须了解基本的SELECT 、 UPDATE、DELETE等语句,以及如何进行过滤和排序。 2. 数据类型: 学习PL/SQL必须知道常用的数据类型,例如VARCHAR2、 NUMBER、 DATE等等。这些类型决定着如何进行数据操纵和存储。必须了解数据类型的用法和限制。 3. 基本结构和控制流语句: PL/SQL使用了面向对象的语言结构,例如块(BEGIN/END)和IF/THEN条件语句。还需要掌握循环语句,包括WHILE、FOR、LOOP等。 4. 存储过程存储过程是PL/SQL编程的基础,它是数据库的预定义程序集合。学习存储过程可以提高代码的可重用性、简化维护工作,同时也可以提高性能、增强安全性。 5. 函数和触发器: PL/SQL函数也是预定义程序,它像存储过程一样接收输入参数并返回结果。触发器是在数据表上定义的代码块,可以在特定条件下自动执行。函数和触发器可以极大地简化业务逻辑和提高数据库的完整性和一致性。 6. 调试技巧: PL/SQL开发过程中,调试技巧非常重要。必须掌握如何设置断点、单步调试、观察变量等技巧,以及如何使用Oracle SQL Developer等开发工具进行调试和验证。 总之,PL/SQL学习需积累经验,多实践、多交流,通过参考Oracle技术文档、书籍等所获取的知识,逐步提高编程技巧和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值