Oracle procedure 存储过程

2024-02-18 09:58
文章标签 oracle 过程 存储 procedure

本文主要是介绍Oracle procedure 存储过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Oracle procedure 存储过程

Oracle procedure 基本语法:

CREATE [OR REPLACE] PROCEDURE 存储过程名[(参数 [IN|OUT|INOUT] 数据类型...)]
{IS|AS}
[说明部分,例如:变量声明]
BEGIN 
可执行部分
[EXCEPTION
错误处理部分]
END [存储过程名];
/


-- 创建存储过程
-- create procedure 'testproc'
create or replace procedure testproc
as
  cnt number(38);
begin
  select count(*) into cnt from dual;
  dbms_output.put_line('cnt: '||cnt);
end;
/


注意:
1.在 PROCEDURE 和 FUNCTION 中使用 IS/AS 并没有太大区别。但在 VIEW 中只能用 AS 而不能用 IS ,在 CURSOR 中只能用 IS 而不能用AS。IS/AS 后面一般跟变量声明。 


-- 查询创建的存储过程
col name for a30;
col type for a20;

-- show all
select * from user_source;

-- show some
select * from user_source where name like upper('%test%');

-- show one
select * from user_source where name = upper('testproc');


-- 查询存储过程状态(包括编译成功与否状态)
col object_name for a20;
col subobject_name for a20;
select object_name, status, last_ddl_time, created, timestamp from user_objects where object_name = upper('testproc');


-- 调用存储过程
-- call procedure 'testproc'
set serveroutput on;
begin
  testproc;
end;
/

直接在SQL命令行执行命令调用存储过程
set serveroutput on;
execute testproc;


-- 重新编译存储过程
alter procedure testproc compile;
select object_name, status, last_ddl_time, created, timestamp from user_objects where object_name = upper('testproc');


删除存储过程
drop procedure testpro;

 

使用游标查询多行结果集

SQL Server支持存储过程中使用 select * from  student 来查询结果集,但Oracle不支持,会报错Warning: Procedure  created  with  compilation  errors。
Oracle中可以使用游标来返回结果集合。

-- 查询结果为多行结果集。student表三个字段:id,name,age
create or replace procedure testproc2
is
  cursor cur_all is select id,name,age from student;  --定义游标 cur_all
  c_id student.id%type;     --声明变量分别用来保存查询表的各列
  c_name student.name%type;
  c_age student.age%type;
begin
open cur_all;        --打开游标
  loop                    --循环处理
    fetch cur_all into c_id,c_name,c_age;    --操作数据
    exit when cur_all%NOTFOUND;            --循环退出条件:最近的FETCH语句返回一行数据则为FALSE
    if cur_all%FOUND then                          --最近的FETCH语句返回一行数据则为TRUE
      dbms_output.put_line(c_id||' '||c_name||' '||c_age);
    end if;
  end loop;
close cur_all;     --关闭游标
end;
/

execute testproc2;
1 jack 20
2 lucy 21
3 happy 20
4 white 21
 

--带入参(IN)的存储过程,普通循环1
create or replace procedure testproc2(var1 in varchar2 default 'id name age')
is
  cursor cur_all is select id,name,age from student;  --定义游标 cur_all
  c_id student.id%type;                               --声明变量分别用来保存查询表的各列
  c_name student.name%type;
  c_age student.age%type;
begin
dbms_output.put_line(var1);
open cur_all;                                         --打开游标
  loop                                                --循环处理
    fetch cur_all into c_id,c_name,c_age;             --操作数据
    exit when cur_all%NOTFOUND;                       --循环退出条件:最近的FETCH语句返回一行数据则为FALSE
    if cur_all%FOUND then                             --最近的FETCH语句返回一行数据则为TRUE
      dbms_output.put_line(c_id||' '||c_name||' '||c_age);
    end if;
  end loop;
close cur_all;                                        --关闭游标
end;
/


--带入参(IN)的存储过程,普通循环2
create or replace procedure testproc2(var1 in varchar2 default 'id name age')
is
  cursor cur_all is select * from student;  --定义游标 cur_all
  cur_line student%rowtype;                 --定义rowtype
begin
dbms_output.put_line(var1);
open cur_all;                                         --打开游标
  loop                                                --循环处理
    fetch cur_all into cur_line;                      --操作数据
    exit when cur_all%NOTFOUND;                       --循环退出条件:最近的FETCH语句返回一行数据则为FALSE
    if cur_all%FOUND then                             --最近的FETCH语句返回一行数据则为TRUE
      dbms_output.put_line(cur_line.id||' '||cur_line.name||' '||cur_line.age);
    end if;
  end loop;
close cur_all;                                        --关闭游标
end;
/

 

execute testproc2
id name age
1 jack 20
2 lucy 21
3 happy 20
4 white 21

execute testproc2('id2, name2, age2')
id2, name2, age2
1 jack 20
2 lucy 21
3 happy 20
4 white 21

call testproc2();
id name age
1 jack 20
2 lucy 21
3 happy 20
4 white 21

call testproc2('id3 name3 age3');
id3 name3 age3
1 jack 20
2 lucy 21
3 happy 20
4 white 21
 

--带入参(IN)的存储过程,用"for in"使用cursor(游标)
create or replace procedure testproc2(var1 in varchar2 default 'id name age')
is
  cursor cur_all is select * from student;  --定义游标 cur_all
  cur_line student%rowtype;                 --定义rowtype
begin
dbms_output.put_line(var1);
  for cur_line in cur_all loop              --循环处理,隐式打开游标
    dbms_output.put_line(cur_line.id||' '||cur_line.name||' '||cur_line.age); --隐式执行一个fetch
  end loop;
--隐式关闭游标
end;
/
 

--带入参(IN)的存储过程,用 bulk collect 批量检索,效率更高
create or replace procedure testproc2(var1 in varchar2 default 'id name age')
is
  cursor cur_all is select * from student;      --定义游标 cur_all
  type student_tab is table of student%rowtype; --定义类型 student_tab
  student_rd student_tab;                       --定义变量 student_rd
begin
  dbms_output.put_line(var1);
  open cur_all;
  loop                   --循环处理,隐式打开游标
    fetch cur_all bulk collect into student_rd limit 500;
      for i in 1..student_rd.count loop             --循环处理
        dbms_output.put_line(student_rd(i).id||' '||student_rd(i).name||' '||student_rd(i).age);
      end loop;
    exit when cur_all%NOTFOUND;       --循环退出条件:最近的FETCH语句返回一行数据则为FALSE
  end loop;
  close cur_all;
end;
/
 


--带出参(OUT)的存储过程,简单样例
create or replace procedure testproc2(ret out varchar2)
is
begin
  ret := 'test002';
end;
/

declare
ret varchar2(255):='test001';
begin
  dbms_output.put_line(ret); --ret 原值
  testproc2(ret);
  dbms_output.put_line(ret); --ret 新值
end;
/

输出结果:
test001
test002


--带入参(IN)、出参(OUT)的存储过程,用"for in"使用cursor(游标)
create or replace procedure testproc2(var1 in varchar2 default 'id name age', var2 out varchar2)
is
  cursor cur_all is select * from student;  --定义游标 cur_all
  cur_line student%rowtype;                 --定义rowtype
begin
  dbms_output.put_line(var1);
  for cur_line in cur_all loop              --循环处理,隐式打开游标
    --dbms_output.put_line(cur_line.id||' '||cur_line.name||' '||cur_line.age); --隐式执行一个fetch
    var2 := var2||cur_line.id||' '||cur_line.name||' '||cur_line.age||chr(13)||chr(10);
  end loop;
--隐式关闭游标
end;
/

执行存储过程
declare
  ret varchar2(8000);
begin
  testproc2('id name age', ret);
  dbms_output.put_line(ret);
end;
/

结果如下:

id name age
1 jack 20
2 lucy 21
3 happy 20
4 white 21

 

这篇关于Oracle procedure 存储过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/720792

相关文章

java变量内存中存储的使用方式

《java变量内存中存储的使用方式》:本文主要介绍java变量内存中存储的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍2、变量的定义3、 变量的类型4、 变量的作用域5、 内存中的存储方式总结1、介绍在 Java 中,变量是用于存储程序中数据

Oracle 通过 ROWID 批量更新表的方法

《Oracle通过ROWID批量更新表的方法》在Oracle数据库中,使用ROWID进行批量更新是一种高效的更新方法,因为它直接定位到物理行位置,避免了通过索引查找的开销,下面给大家介绍Orac... 目录oracle 通过 ROWID 批量更新表ROWID 基本概念性能优化建议性能UoTrFPH优化建议注

PostgreSQL 序列(Sequence) 与 Oracle 序列对比差异分析

《PostgreSQL序列(Sequence)与Oracle序列对比差异分析》PostgreSQL和Oracle都提供了序列(Sequence)功能,但在实现细节和使用方式上存在一些重要差异,... 目录PostgreSQL 序列(Sequence) 与 oracle 序列对比一 基本语法对比1.1 创建序

将图片导入Python的turtle库的详细过程

《将图片导入Python的turtle库的详细过程》在Python编程的世界里,turtle库以其简单易用、图形化交互的特点,深受初学者喜爱,随着项目的复杂度增加,仅仅依靠线条和颜色来绘制图形可能已经... 目录开篇引言正文剖析1. 理解基础:Turtle库的工作原理2. 图片格式与支持3. 实现步骤详解第

Linux系统调试之ltrace工具使用与调试过程

《Linux系统调试之ltrace工具使用与调试过程》:本文主要介绍Linux系统调试之ltrace工具使用与调试过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、ltrace 定义与作用二、ltrace 工作原理1. 劫持进程的 PLT/GOT 表2. 重定

Maven 依赖发布与仓库治理的过程解析

《Maven依赖发布与仓库治理的过程解析》:本文主要介绍Maven依赖发布与仓库治理的过程解析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下... 目录Maven 依赖发布与仓库治理引言第一章:distributionManagement配置的工程化实践1

Spring三级缓存解决循环依赖的解析过程

《Spring三级缓存解决循环依赖的解析过程》:本文主要介绍Spring三级缓存解决循环依赖的解析过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、循环依赖场景二、三级缓存定义三、解决流程(以ServiceA和ServiceB为例)四、关键机制详解五、设计约

spring IOC的理解之原理和实现过程

《springIOC的理解之原理和实现过程》:本文主要介绍springIOC的理解之原理和实现过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、IoC 核心概念二、核心原理1. 容器架构2. 核心组件3. 工作流程三、关键实现机制1. Bean生命周期2.

Redis实现分布式锁全解析之从原理到实践过程

《Redis实现分布式锁全解析之从原理到实践过程》:本文主要介绍Redis实现分布式锁全解析之从原理到实践过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、背景介绍二、解决方案(一)使用 SETNX 命令(二)设置锁的过期时间(三)解决锁的误删问题(四)Re

SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法

《SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法》在SQLyog中执行存储过程时出现的前置缩进问题,实际上反映了SQLyog对SQL语句解析的一个特殊行为,本文给大家介绍了详... 目录问题根源正确写法示例永久解决方案为什么命令行不受影响?最佳实践建议问题根源SQLyog的语句分