热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PL/SQL之--存储过程

一、存储过程存储过程是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。oracle可以把PLSQL程序储

一、存储过程

  存储过程是一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。oracle可以把PL/SQL程序储存在数据库中,并可以在任何地方来运行它。存储过程被称为PL/SQL子程序,是被命名的PL/SQL快,存储在数据库,通过输入、输出参数与调用者交换信息。oracle存储过程不返回数据。

  语法:

  create or replace procudure 存储过名称(  
    参数名称  输入输出类型  参数类型,    
    参数名称  输入输出类型  参数类型  
  )   
  is
  begin
    处理语句;
    exceeption;
      异常处理语句;
  end 存储过名称;

  输出输出类型有如下三种:  

  • IN 定义一个输入参数变量,用于传递参数给存储过程,存储过程无法改变参数值,该参数可以是常量、或是有值的变量。
  • OUT 定义一个输出参数变量,用于从存储过程获取数据,该参数必须是一个变量,该变量是否有值不重要。
  • IN OUT 定义一个输入、输出参数变量,兼有以上两者的功能,该参数必须是一个变量,该变量必须有值。

   输出输出参数类型一般不声明长度,因为对于IN参数,其宽度是由外部决定。 对于OUT 和IN OUT 参数,其宽度是由存储过程内部决定。对于没有说明输入输出类型的参数,默认为IN类型。

二、示例

  以下代码person表结构如下:

DROP TABLE person ;
CREATE TABLE person (
id NUMBER(11) NOT NULL ,
username VARCHAR2(255 ) NULL ,
age NUMBER(11) NULL ,
password VARCHAR2(255) NULL ,
PRIMARY KEY (id)
)
INSERT INTO person  VALUES ('1', '张三', '100', 'zhang123');
INSERT INTO person  VALUES ('2', '李四', '20', 'lisi123');
INSERT INTO person  VALUES ('3', '王五', '20', 'wang123');
INSERT INTO person  VALUES ('4', '赵六', '20', 'zhao123');

  1、查询一个(in、out)

create or replace procedure pro_person_getbyid(
       p_id in number,
       p_username out varchar2,
       p_age out number,
       p_password out varchar2
)
is
begin
  select username, age, password into p_username, p_age, p_password from person where id = p_id;
end pro_person_getbyid;
-- 调用代码 --------------
declare
    v_id number;
    v_username varchar2(255);
    v_age number;
    v_password varchar2(255);
begin
    v_id := 1;
    pro_person_getbyid(v_id, v_username, v_age, v_password);
    dbms_output.put_line('username:'||v_username||' age:'||v_age||' password:'||v_password);
end;

  2、查询一个(in、out)使用rowtype

create or replace procedure pro_person_getrow(
       p_id in number,
       p_row out person%rowtype, -- rowtype类型变量
       p_count out number -- 标记是否找到记录
)
is
begin
  select * into p_row from person where id = p_id;
  p_count := SQL%ROWCOUNT;
  exception
    when no_data_found then
      p_count := 0;
end pro_person_getrow;
-- 调用--------------
declare
    v_id number := 28;
    v_row person%rowtype;
    v_count number;
begin
  pro_person_getrow(v_id, v_row, v_count);
  dbms_output.put_line(v_count);
  dbms_output.put_line('id:'||v_row.id||' username:'||v_row.username||' age:'||v_row.age||' password:'||v_row.password);
end;

  3、添加记录(in、out) 

create or replace procedure pro_person_insert(
       p_id number,
       p_username varchar2,
       p_age number,
       p_password varchar2,
       p_count out number -- 是否添加成功
)
is
begin
   insert into person (id, username, age, password) values(p_id, p_username, p_age, p_password);
   p_count := SQL%ROWCOUNT;  -- SQL%ROWCOUNT为 隐式游标的属性
   commit;
   exception
     when others then
     p_count := 0; -- 失败
end pro_person_insert;

-- 调用procedure
declare
  v_id number := 28;
  v_username varchar2(255) := 'xiaoli';
  v_age number := 19;
  v_password varchar2(255) := 'xiao123';
  v_count number;
begin
  pro_person_insert(p_id  => v_id, p_username  => v_username, p_age => v_age, p_password => v_password, p_count => v_count);
 --  pro_person_insert(v_id , v_username, v_age, v_password, v_count);
  dbms_output.put_line('影响行数'||v_count);
end;

   4、更新(in、out)

create or replace procedure pro_person_update(
       p_id number,
       p_age number,
       p_password varchar2,
       p_count out number
)
is
begin
  update person set age = p_age, password = p_password where id = p_id;
  p_count := SQL%ROWCOUNT;
  commit;
  exception
    when no_data_found then   
      p_count := 0;
    when others then
      p_count := -1;
end pro_person_update;
-- 调用---------------------
declare
    v_id number := 28;
    v_age number := 19;
    v_password varchar2(255) := 'password';
    v_count number;
begin
  pro_person_update(v_id, v_age, v_password, v_count);
    dbms_output.put_line('影响行数'||v_count);
end;

  5、删除(in、out)

create or replace procedure pro_person_delete(
       p_id number,
       p_count out number
)
is
begin
  delete from person where id = p_id;
  p_count := SQL%ROWCOUNT;
  commit;
  exception
    when no_data_found then   
      p_count := 0;
    when others then
      p_count := -1;    
end pro_person_delete;
-- 调用----------------
declare
    v_id number := 28;
    v_count number;
begin
  pro_person_delete(v_id, v_count);
  dbms_output.put_line('影响行数'||v_count);
end;

   6、查询所有(in、out)使用sys_refcursor

create or replace procedure pro_person_findall2( 
       p_cursor out sys_refcursor -- 输出参数为包类型
)
is
begin 
  open p_cursor for
  select *  from person;  
  exception
  when others then
    DBMS_OUTPUT.PUT_LINE('获取信息发生错误');
end pro_person_findall2;

----调用---------------------------------------------------
declare
    c_cursor sys_refcursor;
    r_person person%rowtype;
begin
  pro_person_findall2(c_cursor);
  --2、打开游标
--  open c_cursor; --此处不需要显示地打开游标,因为调用存储过程的时候返回的游标已经打开了
  --3、提取数据
  loop
    fetch c_cursor 
    into r_person;
    exit when c_cursor%notfound; -- 下面没有数据的时候,退出
    dbms_output.put_line('id:'||r_person.id);
    dbms_output.put_line('username:'||r_person.username);
    dbms_output.put_line('age:'||r_person.age); 
  end loop; 
end;

  7、查询所有(in、out)使用自定义类型查询

-- 创建一个包类型
create or replace package pkg_const as
  type r_cursor is ref cursor;
end  pkg_const;

-- 创建存储过程,
create or replace procedure pro_person_findall( 
       p_cursor out pkg_const.r_cursor -- 输出参数为包类型
)
is
begin 
  open p_cursor for
  select *  from person;  
  exception
  when others then
    DBMS_OUTPUT.PUT_LINE('获取信息发生错误');
end pro_person_findall;

----调用------------------------------------
declare
    c_cursor pkg_const.r_cursor;
    r_person person%rowtype;
begin
  pro_person_findall(c_cursor);
  --2、打开游标
--  open c_cursor;
  --3、提取数据
  loop
    fetch c_cursor 
    into r_person;
    exit when c_cursor%notfound; -- 下面没有数据的时候,退出
    dbms_output.put_line('id:'||r_person.id);
    dbms_output.put_line('username:'||r_person.username);
    dbms_output.put_line('age:'||r_person.age); 
  end loop; 
end;

三、存储过程其他语句

  查看存储过程

DESCRIBE 存储过程名;

  删除存储过程

DROP PROCEDURE 存储过程名;

 


推荐阅读
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
  • Python操作MySQL(pymysql模块)详解及示例代码
    本文介绍了使用Python操作MySQL数据库的方法,详细讲解了pymysql模块的安装和连接MySQL数据库的步骤,并提供了示例代码。内容涵盖了创建表、插入数据、查询数据等操作,帮助读者快速掌握Python操作MySQL的技巧。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
author-avatar
鄙人灵魔世界
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有