懵懂oracle之存储过程2

Posted 滚雪球俱乐部

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了懵懂oracle之存储过程2相关的知识,希望对你有一定的参考价值。

      上篇《懵懂oracle之存储过程》已经给大家介绍了很多关于开发存储过程相关的基础知识,笔者尽最大的努力总结了所有接触到的关于存储过程的知识,分享给大家和大家一起学习进步。本篇文章既是完成上篇文章中未来得及总结的关于存储过程的调用、测试等知识的汇总分享,也是对上篇文章的存储过程的一个调试改错过程(由于知识的局限性和书写时的疏忽等,之前的存储过程有误之处难免,正在不断更改中,如果能得到大家的指正将使这个工作进行地更快更好,助人为快乐之本!)。

      下面步入正题,介绍本篇知识汇总和分享:

      一、存储过程的调用(下面语句请用于测试窗口执行)(代码中sp_hll_test_20170415这个存储过程可参见《懵懂oracle之存储过程》,请注意查看使用最新的代码)。

 1 declare -- 如果不需要定义参数,那么就可去掉此declare部分,只使用begin……end块
 2   a      number;
 3   b      date;
 4   c      varchar2(20);
 5   d      number;
 6   status user_tables.status%type;
 7   -- e    varchar2(20); 长度过小
 8 /*
 9     务必注意出参或出入参为变量时,变量有长度限制时不得小于在存储过程中会达到的最大值,
10     否则会导致过长的字符串无法存入这个长度不够的变量中,而报错:
11             ORA-06502: PL/SQL: 数字或值错误 :  字符串缓冲区太小
12   */
13   e      varchar2(200);
14 begin
15  /*
16    存储过程调用时,参数可以为常量、变量或绑定变量,参数调用方式可以为定位调用、命名调用或混合调用,
17    同时参数和参数调用方式互不干涉,可随意混合。
18  */ 
19  
20   -- 调用方式1:定位符调用
21   /* 
22     实参和形参通过位置顺序一一对应。
23     如下例调用,第一个参数a传值给sp_hll_test_20170415的入参i_a等。
24   */
25   sp_hll_test_20170415(a, b, c,  d, status, e); 
26 
27   -- 调用方式2:命名符调用
28   /*
29     在每一个参数设置的时候,都可以通过"形参=>实参"的格式,指定形参和实参,
30     这样一来,参数的位置顺序就不必与存储过程创建时规定的顺序一致,可以自由调节。
31     如下例,将参数顺序完全颠倒。
32   */
33   sp_hll_test_20170415(io_e => e,  i_status => status, o_d => d, i_c => c, i_b => b,  i_a => a);
34   
35   -- sp_hll_test_20170415(io_e => e,  i_status => status, o_d => d, o_d => c, i_b => b,  i_a => a);
36   -- 命名符调用时,务必注意形参值别重复,如上例的o_d形参,这样会导致下面的异常:
37   -- PLS-00703: 列表中具有指定参数的多个实例
38 
39   -- 调用方式3:定位符+命名符调用
40   /*
41     上面两种调用方式可混合使用,但是注意,一旦某个参数有使用命名符,则后面所有的参数都得使用命名符,
42     也就是说只能前x个参数为定位符方式,后y个参数为命名符方式(x+y=总参数数目)。
43     否则会导致异常:“PLS-00312:一个定位相关参数没有说明其相关性”
44   */
45   sp_hll_test_20170415(a, b, io_e =>e , i_c =>c,  i_status =>status,  o_d =>d);
46 
47   -- 参数方式:常量+变量
48   a:=3;
49   select sysdate into b from dual;
50   sp_hll_test_20170415(a, b, \'我是常量C\',  d, \'0\', e); 
51   
52   -- sp_hll_test_20170415(a, b, c,  2, status, e); 
53   -- 出参、出入参,不能为常量,因为它们会被赋值
54   -- PLS-00363: 表达式 \'2\' 不能用作赋值目标
55 
56   -- 参数方式:绑定变量
57   /*
58     绑定变量,即冒号+变量名称,这种方式我们在之前的存储过程学习中也有接触,在PLSQL
59     的测试窗口中,对于绑定变量可在窗口下侧的“变量-类型-值”区域右键进行增加删除等,可一一设定值,
60     同时出参、出入参在变化后也会体现到“值”处(当然在F9调试时,不止绑定变量,其它变量也可添加进去,
61     查看每步运行后的值)。
62     ps:PLSQL中在存储过程名称上右键,通过右键菜单中“测试”功能,能迅速打开一个“测试窗口”,
63         窗口内部的调用存储过程方式默认为绑定变量+定位符调用方式,在后续调试教程中有图有真相。
64   */
65   sp_hll_test_20170415(io_e => :e1,  i_status => :status1, o_d => :d1,  i_a => :a1);
66 
67   -- 参数方式:常量+变量+绑定变量
68   sp_hll_test_20170415(1,to_date(\'2017-6-16\', \'yyyy-mm-dd\'), io_e =>e , i_c =>c,  i_status =>:status1,  o_d =>d);
69 
70   -- 默认值使用
71   -- sp_hll_test_20170415(a, b,  status, e); 
72   /* 
73     当存储过程参数含有默认值的参数时,那么在需要使用默认值时一般可省略此参数,
74     但是这样就和定位符调用有冲突,像上例调用,省略的是第三、四位的参数,可对定位符来说,
75     它第三、四位的参数没有少,少的是第五、六位的参数,同时第四位参数为number,而传的e变量是varchar2(200)
76     所以就会导致异常:       PLS-00306: 调用 \'SP_HLL_TEST_20170415\' 时参数个数或类型错误
77 
78     因此如果既想使用定位符调用方式,又想能使用默认值方式,那么必须在存储过程定义的时候,
79     把具有默认值的参数反正参数列表的最后。
80   */
81   -- 或者可用命名符调用的方式来使用默认值,如下例:
82   sp_hll_test_20170415(io_e => :e1,  i_status => status, o_d => d,  i_a => a);
83 
84 end;

 

      二、存储过程的调试。

      0.调试前提条件,用户必须拥有调试的权限,否则“ORA-01031: insufficient privileges”会找你麻烦。

         解决方法:用管理员账号给此用户赋予权限

1 grant debug any procedure, debug connect session to 用户;

      1.可通过下图方式快捷进入单个存储过程的“测试窗口”。

      注意:若存储过程无法调试,只显示正在执行,单步进入、退出等按钮无法使用,无法打断点等情况,请核查数据库是否采用了负载均衡,这时得将本机tns配置成下例情况,采用单节点登录:

 1 test_one_node =
 2   (description =
 3   (address_list =
 4     # 其中一个机器的ip及port信息
 5     (address = (protocol = tcp)(host = *.*.*.* )(port = *))
 6     )
 7     (connect_data =
 8         (server = dedicated)
 9       (service_name = *)
10       # show parameter instance_name 或者select instance_name from v$instance 可查看此值
11       (instance_name = *)
12     )  
13   ) 

 

      2.亦可在新打开或已有的一个“测试窗口”中,仿照一例书写各种代码进行测试(甚至可以在测试单个存储过程时,将“create or replace procedure sp_hll_test_20170415……”创建存过及定义参数部分替换成一例中的declare部分+补充好缺少的参数信息,来测试这个存储过程。这种方式和把此存储过程“添加调试信息”后调试入存储过程内部也差不了多少,可看喜好或场景等按需使用)。

 

 

       3.调试需知(只介绍一些常用项,其它的可自己探索)。

      单步进入+单步退出=单步跳过。

 

作者:滚雪球俱乐部-何理利

出处: http://www.cnblogs.com/snowballed/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 原文链接
如有疑问, 可邮件(he.lili1@ztesoft.com)咨询。

以上是关于懵懂oracle之存储过程2的主要内容,如果未能解决你的问题,请参考以下文章

Oracle之存储过程

PostgreSQL Oracle 兼容性之存储过程

Oracle系列:(29)存储过程和存储函数

Oracle之存储过程

从Oracle存储过程Oracle 11g发送邮件

oracle之存储过程