`

存储过程常用技巧1

阅读更多

我们在进行pl/sql编程时打交道最多的就是存储过程了。存储过程的结构是非常的简单的,我们在这里除了学习存储过程的基本结构外,还会学习编写存储过程时相关的一些实用的知识。如:游标的处理,异常的处理,集合的选择等等

1.存储过程结构
1.1 第一个存储过程

Java代码 复制代码
  1. create or replace procedure proc1(   
  2.   p_para1 varchar2,   
  3.   p_para2 out varchar2,   
  4.   p_para3 in out varchar2   
  5. )as    
  6.  v_name varchar2(20);   
  7. begin   
  8.   v_name := '张三丰';   
  9.   p_para3 := v_name;   
  10.   dbms_output.put_line('p_para3:'||p_para3);   
  11. end;  
create or replace procedure proc1(
  p_para1 varchar2,
  p_para2 out varchar2,
  p_para3 in out varchar2
)as 
 v_name varchar2(20);
begin
  v_name := '张三丰';
  p_para3 := v_name;
  dbms_output.put_line('p_para3:'||p_para3);
end;



上面就是一个最简单的存储过程。一个存储过程大体分为这么几个部分:
创建语句:create or replace procedure 存储过程名
如果没有or replace语句,则仅仅是新建一个存储过程。如果系统存在该存储过程,则会报错。Create or replace procedure 如果系统中没有此存储过程就新建一个,如果系统中有此存储过程则把原来删除掉,重新创建一个存储过程。
存储过程名定义:包括存储过程名和参数列表。参数名和参数类型。参数名不能重复, 参数传递方式:IN, OUT, IN OUT
IN 表示输入参数,按值传递方式。
OUT 表示输出参数,可以理解为按引用传递方式。可以作为存储过程的输出结果,供外部调用者使用。
IN OUT 即可作输入参数,也可作输出参数。
参数的数据类型只需要指明类型名即可,不需要指定宽度。
参数的宽度由外部调用者决定。
过程可以有参数,也可以没有参数
变量声明块:紧跟着的as (is )关键字,可以理解为pl/sql的declare关键字,用于声明变量。
变量声明块用于声明该存储过程需要用到的变量,它的作用域为该存储过程。另外这里声明的变量必须指定宽度。遵循PL/SQL的变量声明规范。
过程语句块:从begin 关键字开始为过程的语句块。存储过程的具体逻辑在这里来实现。
异常处理块:关键字为exception ,为处理语句产生的异常。该部分为可选
结束块:由end关键字结果。

1.2 存储过程的参数传递方式
存储过程的参数传递有三种方式:IN,OUT,IN OUT .
IN 按值传递,并且它不允许在存储过程中被重新赋值。如果存储过程的参数没有指定存参数传递类型,默认为IN

Java代码 复制代码
  1. create or replace procedure proc1(   
  2.   p_para1 varchar2,   
  3.   p_para2 out varchar2,   
  4.   p_para3 in out varchar2   
  5. )as    
  6.  v_name varchar2(20);   
  7. begin   
  8.   p_para1 :='aaa';   
  9.   p_para2 :='bbb';   
  10.   v_name := '张三丰';   
  11.   p_para3 := v_name;   
  12.   dbms_output.put_line('p_para3:'||p_para3);   
  13.   null;   
  14. end;   
  15.        
  16. Warning: Procedure created with compilation errors   
  17.   
  18. SQL> show error;   
  19. Errors for PROCEDURE LIFEMAN.PROC1:   
  20.   
  21. LINE/COL ERROR   
  22. -------- ----------------------------------------------------------------------   
  23. 8/3      PLS-00363: expression 'P_PARA1' cannot be used as an assignment target   
  24. 8/3      PL/SQL: Statement ignored  
create or replace procedure proc1(
  p_para1 varchar2,
  p_para2 out varchar2,
  p_para3 in out varchar2
)as 
 v_name varchar2(20);
begin
  p_para1 :='aaa';
  p_para2 :='bbb';
  v_name := '张三丰';
  p_para3 := v_name;
  dbms_output.put_line('p_para3:'||p_para3);
  null;
end;
	
Warning: Procedure created with compilation errors

SQL> show error;
Errors for PROCEDURE LIFEMAN.PROC1:

LINE/COL ERROR
-------- ----------------------------------------------------------------------
8/3      PLS-00363: expression 'P_PARA1' cannot be used as an assignment target
8/3      PL/SQL: Statement ignored

这一点与其它高级语言都不同。它相当于java在参数前面加上final关键字。


OUT 参数:作为输出参数,需要注意,当一个参数被指定为OUT类型时,就算在调用存储过程之前对该参数进行了赋值,在存储过程中该参数的值仍然是null.

Java代码 复制代码
  1. create or replace procedure proc1(   
  2.   p_para1 varchar2,   
  3.   p_para2 out varchar2,   
  4.   p_para3 in out varchar2   
  5. )as    
  6.  v_name varchar2(20);   
  7. begin   
  8.   v_name := '张三丰';   
  9.   p_para3 := v_name;   
  10.   dbms_output.put_line('p_para1:'||p_para1);   
  11.   dbms_output.put_line('p_para2:'||p_para2);   
  12.   dbms_output.put_line('p_para3:'||p_para3);   
  13. end;   
  14.   
  15. SQL> var p1 varchar2(10);   
  16. SQL> var p2 varchar2(10);   
  17. SQL> var p3 varchar2(10);   
  18. SQL> exec :p1 :='aaaa';   
  19. SQL> exec :p2 :='bbbb';   
  20. SQL> exec :p3 :='cccc';   
  21. SQL> exec proc1(:p1,:p2,:p3);   
  22. p_para1:aaaa   
  23. p_para2:   
  24. p_para3:张三丰   
  25. SQL> exec dbms_output.put_line(:p2);   
  26.   
  27.   
  28. PL/SQL procedure successfully completed   
  29. p2   
  30. ---------  
create or replace procedure proc1(
  p_para1 varchar2,
  p_para2 out varchar2,
  p_para3 in out varchar2
)as 
 v_name varchar2(20);
begin
  v_name := '张三丰';
  p_para3 := v_name;
  dbms_output.put_line('p_para1:'||p_para1);
  dbms_output.put_line('p_para2:'||p_para2);
  dbms_output.put_line('p_para3:'||p_para3);
end;

SQL> var p1 varchar2(10);
SQL> var p2 varchar2(10);
SQL> var p3 varchar2(10);
SQL> exec :p1 :='aaaa';
SQL> exec :p2 :='bbbb';
SQL> exec :p3 :='cccc';
SQL> exec proc1(:p1,:p2,:p3);
p_para1:aaaa
p_para2:
p_para3:张三丰
SQL> exec dbms_output.put_line(:p2);


PL/SQL procedure successfully completed
p2
---------


INOUT 是真正的按引用传递参数。即可作为传入参数也可以作为传出参数。

Java代码 复制代码
  1. 1.3 存储过程参数宽度   
  2. create or replace procedure proc1(   
  3.   p_para1 varchar2,   
  4.   p_para2 out varchar2,   
  5.   p_para3 in out varchar2   
  6. )as    
  7.  v_name varchar2(2);   
  8. begin   
  9.   v_name := p_para1;   
  10. end;   
  11.   
  12. SQL> var p1 varchar2(10);   
  13. SQL> var p2 varchar2(20);   
  14. SQL> var p3 varchar2(30);   
  15. SQL> exec :p1 :='aaaaaa';   
  16. SQL> exec proc1(:p1,:p2,:p3);   
  17.        
  18.        
  19. ORA-06502: PL/SQL: numeric or value error: character string buffer too small   
  20. ORA-06512: at "LIFEMAN.PROC1", line 8  
  21. ORA-06512: at line 1  
1.3 存储过程参数宽度
create or replace procedure proc1(
  p_para1 varchar2,
  p_para2 out varchar2,
  p_para3 in out varchar2
)as 
 v_name varchar2(2);
begin
  v_name := p_para1;
end;

SQL> var p1 varchar2(10);
SQL> var p2 varchar2(20);
SQL> var p3 varchar2(30);
SQL> exec :p1 :='aaaaaa';
SQL> exec proc1(:p1,:p2,:p3);
	
	
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "LIFEMAN.PROC1", line 8
ORA-06512: at line 1


首先,我们要明白,我们无法在存储过程的定义中指定存储参数的宽度,也就导致了我们无法在存储过程中控制传入变量的宽度。这个宽度是完全由外部传入时决定的。
我们再来看看OUT类型的参数的宽度。

Java代码 复制代码
  1. create or replace procedure proc1(   
  2.   p_para1 varchar2,   
  3.   p_para2 out varchar2,   
  4.   p_para3 in out varchar2   
  5. )as    
  6.  v_name varchar2(2);   
  7. begin   
  8.   p_para2 :='aaaaaaaaaaaaaaaaaaaa';   
  9. end;   
  10. SQL> var p1 varchar2(1);   
  11. SQL> var p2 varchar2(1);   
  12. SQL> var p3 varchar2(1);   
  13. SQL> exec :p2 :='a';   
  14. SQL> exec proc1(:p1,:p2,:p3);  
create or replace procedure proc1(
  p_para1 varchar2,
  p_para2 out varchar2,
  p_para3 in out varchar2
)as 
 v_name varchar2(2);
begin
  p_para2 :='aaaaaaaaaaaaaaaaaaaa';
end;
SQL> var p1 varchar2(1);
SQL> var p2 varchar2(1);
SQL> var p3 varchar2(1);
SQL> exec :p2 :='a';
SQL> exec proc1(:p1,:p2,:p3);

在该过程中,p_para2被赋予了20个字符a.
而在外部的调用过程中,p2这个参数仅仅被定义为varchar2(1).
而把p2作为参数调用这个过程,却并没有报错。而且它的真实值就是20个a

Java代码 复制代码
  1. SQL> select dump(:p2) from dual;   
  2. DUMP(:P2)   
  3. ---------------------------------------------------------------------------   
  4. Typ=1 Len=2097,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97  
  5. p2   
  6. ---------   
  7. aaaaaaaaaaaaaaaaaaaa   
  8.        
  9.     再来看看IN OUT参数的宽度   
  10. create or replace procedure proc1(   
  11.   p_para1 varchar2,   
  12.   p_para2 out varchar2,   
  13.   p_para3 in out varchar2   
  14. )as    
  15.  v_name varchar2(2);   
  16. begin   
  17.   p_para3 :='aaaaaaaaaaaaaaaaaaaa';   
  18. end;   
  19.   
  20. SQL> var p1 varchar2(1);   
  21. SQL> var p2 varchar2(1);   
  22. SQL> var p3 varchar2(1);   
  23. SQL> exec proc1(:p1,:p2,:p3);  
SQL> select dump(:p2) from dual;
DUMP(:P2)
---------------------------------------------------------------------------
Typ=1 Len=20: 97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97
p2
---------
aaaaaaaaaaaaaaaaaaaa
	
	再来看看IN OUT参数的宽度
create or replace procedure proc1(
  p_para1 varchar2,
  p_para2 out varchar2,
  p_para3 in out varchar2
)as 
 v_name varchar2(2);
begin
  p_para3 :='aaaaaaaaaaaaaaaaaaaa';
end;

SQL> var p1 varchar2(1);
SQL> var p2 varchar2(1);
SQL> var p3 varchar2(1);
SQL> exec proc1(:p1,:p2,:p3);

执行这个过程,仍然正确执行。

可见,对于IN参数,其宽度是由外部决定。
对于OUT 和IN OUT 参数,其宽度是由存储过程内部决定。
因此,在写存储过程时,对参数的宽度进行说明是非常有必要的,最明智的方法就是参数的数据类型使用%type。这样双方就达成了一致。

1.3 参数的默认值
存储过程的参数可以设置默认值

Java代码 复制代码
  1. create or replace procedure procdefault(p1 varchar2,   
  2.                                         p2 varchar2 default 'mark')   
  3. as    
  4. begin   
  5.   dbms_output.put_line(p2);   
  6. end;   
  7.   
  8. SQL> set serveroutput on;   
  9. SQL> exec procdefault('a');  
create or replace procedure procdefault(p1 varchar2,
                                        p2 varchar2 default 'mark')
as 
begin
  dbms_output.put_line(p2);
end;

SQL> set serveroutput on;
SQL> exec procdefault('a');

mark
可以通过default 关键字为存储过程的参数指定默认值。在对存储过程调用时,就可以省略默认值。
需要注意的是:默认值仅仅支持IN传输类型的参数。OUT 和 IN OUT不能指定默认值

对于有默认值的参数不是排在最后的情况。

Java代码 复制代码
  1. create or replace procedure procdefault2(p1 varchar2 default 'remark',   
  2.                                         p2 varchar2 )   
  3. as    
  4. begin   
  5.   dbms_output.put_line(p1);   
  6. end;  
create or replace procedure procdefault2(p1 varchar2 default 'remark',
                                        p2 varchar2 )
as 
begin
  dbms_output.put_line(p1);
end;

第一个参数有默认值,第二个参数没有。如果我们想使用第一个参数的默认值时
exec procdefault2('aa');
这样是会报错的。
那怎么变呢?可以指定参数的值。

Java代码 复制代码
  1. SQL> exec procdefault2(p2 =>'aa');  
SQL> exec procdefault2(p2 =>'aa');


remark
这样就OK了,指定aa传给参数p2

分享到:
评论

相关推荐

    oracle存储过程常用技巧

    oracle学习中存储过程常用技巧,简单易懂。适合初学者

    oracle存储过程常用的一些功能

    介绍oracle存储过程的常用使用技巧

    oracle存储过程常用的技巧(详)

    存储过程是在大型数据库系统中存储过程在数据库中经过第一次编译后就不需要再次编译,用户通过指定存储过程的名字并给出参数来,通过本篇文章带领大家去学习oracle存储过程常用的技巧,感兴趣的朋友一起来学习吧

    VB常用技巧合集

    VB常用技巧合集 chm全集,比如ActiveX .Exe .Dll Server的多执行绪,ADO/DAO Bolb资料的存取,ADO/RDO Concurrency for SQL 的比较,ADO 连线的其他注意事项,ADO阶层式资料库表达,ADO设定独占性的资料库,Check两...

    oracle数据库中查看系统存储过程的方法

    您可能感兴趣的文章:Oracle存储过程游标用法分析oracle存储过程常用的技巧(详)asp.net中调用oracle存储过程的方法C#调用Oracle存储过程的方法oracle 存储过程详细介绍(创建,删除存储过程,参数传递等)Oracle存储...

    Oracle常用代码技巧

    java调用Oracle的存储过程 Oracle实现分页

    Cognos常用开发技巧及答疑

    主要内容: Framework Manager 分层设计思想、存储过程运用 Report Studio 报表类型选择、条件变量运用、聚合方式选择、报表数据处理 RIDE 特殊参数设计、报表调用

    ASP.NET技巧收集

    Asp.net页面内传参数方法,调用存储过程(两种方法比较),调用存储过程通用类DBHelper,加密解密,SQL常用DBHelper,Asp.net存储过程无限分类,TreeView无限分类,无限分类MVC,荧光棒效果 获取控件上全选,回车转换...

    MySQL存储过程概念、原理与常见用法详解

    主要介绍了MySQL存储过程概念、原理与常见用法,结合实例形式详细分析了mysql存储过程的概念、原理、创建、删除、调用等各种常用技巧与相关注意事项,需要的朋友可以参考下

    常用SQL 语句大全

    11:查看与某一个表相关的视图、存储过程、函数 12:查看当前数据库中所有存储过程 13:查询用户创建的所有数据库 14:查询某一个表的字段和数据类型 15:不同服务器数据库之间的数据操作 SQL Server基本函数 ...

    MySQL数据库常用操作技巧总结

    本文实例总结了MySQL数据库常用操作技巧。分享给大家供大家参考,具体如下: 一、查询不同表中同名字段(表连接查询条件神器) use information_schema; select * from columns where column_name='\u5b57\u6bb5\u...

    asp.net开发常用整理集合

     调用存储过程(两种方法比较)  调用存储过程通用类DBHelper  加密解密  SQL常用DBHelper  Asp.net存储过程无限分类  TreeView无限分类  无限分类MVC  荧光棒效果 获取控件上全选  回车转换成Tab ...

    C#开发经验技巧宝典

    0925 如何获取数据库中的全部存储过程 540 0926 如何正确认识触发器 541 0927 Update触发器在系统日志中的应用 542 0928 触发器的嵌套使用 542 0929 获取数据库中的触发器 543 19.12 其他 544 0930 在...

    sql 常用技巧整理

    ALTER TABLE –修改数据库表结构 CREATE VIEW –创建一个视图 DROP VIEW –从数据库中删除视图 CREATE INDEX –为数据库表创建一个索引 DROP INDEX –从数据库中删除索引 CREATE PROCEDURE –创建一个存储过程 DROP ...

    [Visual.C..编程技巧精选500例]源代码.随书附盘.pdf

    消息框、常用控件、通用对话框、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序版权信息、...

    Oracle优化日记:一个金牌DBA的故事 白鳝.扫描版

    自动段存储空间管理35月27日 无奈今日点评优化小技巧 临时表空间和排序优化小技巧 undo表空间和回滚段5月28日 BBED的妙用今日点评优化小技巧 如何启用BBED优化小技巧 模拟ORA-8102及处理过程优化小技巧 如何计算数据...

    oracle .

    常用技巧 Oracle PL/SQL基础 PL/SQL 块结构和组成元素 PL/SQL 处理流程 光标的使用 错误处理 存储过程和函数 创建包和使用包 触发器 外部存储过程 会话间通信 数据库作业和文件I/O 在PL/SQL 使用SQL语句 PL/SQL程序...

Global site tag (gtag.js) - Google Analytics