使用plsql developer创建存储过程以及调试

前言~

      今天莫名的接到一个任务,需要使用oracle定时任务和oracle存储过程来每日创建一个日志表,由于小编呢尚未接触过存储过程和定时任务,所以今天学习了一番,特定来总结一下。望能给予一些未接触过存储过程的小伙伴一些帮助。


       今入今天的正题,首先要了解一下oracle的存储过程,都有哪些结构,而plsql是一个辅助工具,是能帮助我们更轻松的实现存储过程。

上述就是一个无参的存储过程实例,一个存储过程大体分为这么几个部分:

1)、创建语句:create or replace procedure 存储过程名称 [authid current_user]

         “”[]“”中括号的内容是可选的,其表示修改存储过程,加入authid current_user时存储过程可以使用role权限。

       如果没有or replace语句,那只是新建一个存储过程,如果系统中存在相同的存储过程,则会报错,Create or replace procedure 如果系统中没有此存储过程就新建一个,如果系统中有此存储过程则把原来删除掉,重新创建一个存储过程。

       存储过程名定义:包括存储过程名参数列表参数名参数类型。参数列表可不写,如例子所示。参数名不能重复,并且每个参数之间用分号“   ;” 隔开, 参数传递方式:IN, OUT, IN OUT。如下面例子所示:

下面说明一下参数传递方式:

        in:表示输入参数,调用存储过程时从外面传进来的,它的值不能修改。 

        out:表示输出参数,当一个参数被指定为OUT类型时,如果还未调用存储过程之前对该参数进行了赋值,那么在存储过程中该参数的值仍然是null,但是如果在调用过程中对该参数进行赋值,那么值不为null。

        in out:表示输入输出参数,它的值可以修改。

参数的数据类型只需要指明类型名即可,不需要指定宽度。参数的宽度由外部调用者决定。过程可以有参数,也可以没有参数。

我们看到例子中存在一个“”as“”,它表示变量声明块,可以理解为plsql中的declare关键字,用于声明变量。除了as外,还有is。变量声明块用于声明该存储过程需要用到的变量,它的作用域为该存储过程。另外这里声明的变量必须指定宽度。遵循PL/SQL的变量声明规范。

       其中,as和is的区别:在视图(VIEW)中只能用AS不能用IS;

                                           在游标(CURSOR)中只能用IS不能用AS。

过程语句块:从begin 关键字开始为过程的语句块。存储过程的具体逻辑在这里来实现。

异常处理块:关键字为exception ,为处理语句产生的异常。该部分为可选

结束块:由end关键字结果。


2)、下面讲解一下参数列表中参数的默认值

通过default 关键字为存储过程的参数指定默认值。在对存储过程调用时,就可以省略默认值。

值得注意的是:默认值仅仅支持IN传输类型的参数。OUT 和 IN OUT不能指定默认值

上述情况是default关键字修饰的是最后一个参数,如果是修饰第一个参数呢?

如果我们想使用第一个参数的默认值时,exec procdefault2('aa'); 这样是会报错的。

那怎么变呢?可以指定参数的值。

SQL> exec procdefault2(p2 =>'aa');   这样就OK了,指定aa传给参数p2。


3)、继续讲解存储过程内部块

       我们知道了存储过程的结构,语句块由begin开始,以end结束。这些块是可以嵌套。在语句块中可以嵌套任何以下的块:Declare … begin … exception … end;  

需要注意变量的作用域。  

4)、存储过程中的循环

存储过程的循环语句块有:for...in...loop、while和loop循环。下面分别给予相关实例。

(1)、for...in...loop

实例一 循环遍历游标

create or replace procedure proc_test

as

cursor c1

is

select * from  dat_trade;

begin

for x in c1

loop

dbms_output.put_line (x.id);

end loop;

end proc_test;

实例二 根据数值进行循环

create or replace procedure proc_test (v_num in NUMBER)

as

begin

for x in 1..100 loop

dbms_output.put_line (x);

end loop;

end proc_test;

实例三 在过程里指定输入参数 v_num. 在调用过程时指定循环次数

create or replace procedure proc_test (v_num IN NUMBER)

as

begin

for x in 1 .. v_num

loop

dbms_output.put_line (x);

end loop;

end proc_test;

(2)、loop循环

LOOP

loop

delete from  orders

where senddate < to_char (add_months (sysdate, -3),'yyyy-mm-dd') and rownum < 1000;

exit when SQL%ROWCOUNT < 1;

commit;

end loop;

这里的 SQL%ROWCOUNT 是隐士游标。 除了这个,还有其他几

个:%found,%notfound, %isopen。

(3)while循环

create or replace procedure proc_test (v_num in number)

as

i number := 1;

begin

while i < v_num

loop

begin

i := i + 1;

dbms_output.put_line (i);

end;

end loop;

end proc_test;

5)、 存储过程中的判断

存储过程的判断语句块有:if 条件语句、case ... when ... end case两种

下面给出实例:

(1)、单if实例(if...then...end if; && if...then...else...end if;)

实例一:

create or replace procedure pro_test is

--逻辑判断变量

  exit_table_data varchar2(40);  --判断表数据是否存在

--sql语句执行变量

  execu_sql varchar2(2000);

begin

  execu_sql := 'select count(*) from user';

  execute immediate execu_sql into exit_table_data;

  if exit_table_data=0 then

  execu_sql := 'insert into user values('大明')';

  execute immediate execu_sql;

  commit;

  end if;

end pro_test;

实例二:

create or replace procedure pro_test is

--逻辑判断变量

  exit_table_data varchar2(40);  --判断表数据是否存在

--sql语句执行变量

  execu_sql varchar2(2000);

begin

  execu_sql := 'select count(*) from user';

  execute immediate execu_sql into exit_table_data;

  if exit_table_data=0 then

  execu_sql := 'insert into user values('大明')';

  execute immediate execu_sql;

  commit;

  else

  execu_sql:= 'update user set username='大华'';

  execute immediate execu_sql;

  commit;

  end if;

end pro_test;

(2)、多if实例(if...then...elseif...then...else...end if;)

create or replace procedure proc_test (v_num in number)

as

begin

if v_num < 10

then

dbms_output.put_line (v_num);

elseif v_num > 10 and v_num < 50

then

dbms_output.put_line (v_num - 10);

else

dbms_output.put_line (v_num - 50);

end if;

end proc_test;

(2)、case ... when ... end case

实例一:

create or replace procedure proc_test (v_num in number)

as

begin

case v_num

when 1 then

dbms_output.put_line (v_num);

when 2 then

dbms_output.put_line (v_num);

when 3 then

dbms_output.put_line (v_num);

else null;

end case;

end proc_test;

6)、给变量赋值

       我们在参数列表定义输出参数、输入输出参数yi,以及在参数名位置定义参数,可能都需要一个赋值操作,让查询sql的结果赋值或者定义输入参数赋值等等,那么我们可以使用什么方法给这些参数赋值呢?

       下面列举出一些常用的为变量赋值的方法:

       1、直接法

使用“  :=  ” 的符号为变量赋值,例如: v_pare := "0";

        2、select into

假如变量为v_pare,那么为它赋值的语句为:select count(*) into v_pare from user;

        3、execute immediate 变量名(查询sql语句结果赋值给它的变量)into 变量名

例如:

   v_sqlfalg   := 'select count(*) from user_tables where table_name='''||v_tablename || '''';

   execute immediate v_sqlfalg into v_flag;

   其中,v_tablename、v_sqlfalg、v_flag都是变量;

select into和execute immediate的区别

       1、execute immediate 赋值的变量是通过select语句查询出来的,而select into是直接赋值给变量的。

7)、存储过程跳出循环

oracle存储过程可以使用3种方法跳出循环,分别是return、exit、continue;

它们的区别为:

        1、return是直接跳出存储过程;

        2、如果存在多层循环,exit是直接跳出存储过程的本次循环,而去执行上一级循环的循环条件;

        3、continue是本次循环后面的代码部分不再执行,转而执行本循环的下一次循环。

8)、Oracle存储过程中是否需要写commit的问题

是否需要在存储过程中写commit主要依据需求:

(1) 如果是不需要在存储过程中进行提交,而是由调用程序负责提交或者回滚,那么不需要在存储过程中commit或者rollback。

(2) 如果不想由调用程序负责提交或者回滚,那么就应该在存储过程中进行commit或rollback; 

另外,如果是纯后台数据库开发,一定要写.只是写的时机同样是分为两种,一种是写在过程里面;另一种是写在调用存储过程之后. 而之所以要写commit的原因是,Oracle的默认事务级别是READ COMMITED;默认情况下,Oracle是不会自动提交的,需要手动提交才ok.

9)、使用plsql创建存储过程步骤

1、登录plsql后,在对象框中找到“Procedures”,点击右键,找到新建,如图所示:

2、进入到新建界面,如图所示:

3、最终就进入到存储过程结构中,你要做的就是编写存储过程逻辑。

10)、使用plsql对存储过程进行调试

1、在“Procedures”下拉列表中找到已经编写好的存储过程,点击右键,找到“测试”,如图所示:

2、PL\SQL会打开调试界面,图中位置1的按钮就是开始调试的按钮,在调试之前要填写输入参数的值,位置2就是填写参数的地方,如果有多个参数,会有多行参数框,按参数名填写相应的参数即可,如果没有参数,可以不填。

3、填写完参数,单击开始调试按钮后,调试的界面会发生一些变化。图中位置1的变化,说明存过已经处于执行状态,别人不能再编译或者执行。位置2的按钮就是执行按钮,单击这个按钮存过会执行完成或者遇到bug跳出,否则是不会停下来的,调试时不会用这个按钮的。位置3的按钮才是关键——单步执行,就是让代码一行一行的执行,位置4的按钮是跳出单步执行,等待下一个指令。


今天的课程就讲解到这里,如果有不懂的地方,或者有建议,麻烦下方留言!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • oracle存储过程常用技巧 我们在进行pl/sql编程时打交道最多的就是存储过程了。存储过程的结构是非常的简单的...
    dertch阅读 3,451评论 1 12
  • 1.PLSQL入门 Oracle数据库对SQL进行了扩展,然后加入了一些编程语言的特点,可以对SQL的执行过程进行...
    随手点灯阅读 593评论 0 8
  • 如何把英语作业本设计的更漂亮,让进行业务检查时, 我的能出类拔萃。是给的没有|的英语吧画条|吗? 如果让学生画|,...
    我心我愿秀阅读 1,599评论 1 2
  • 十字打头的年纪,算是青春的始端,无限憧憬,无限遐想。起笔写下初心,对照十年后的自己。 每听一次演讲心中无限遐...
    杜尔比阅读 215评论 0 0
  • 青年的烦恼眼看冬天就要走了外头的风渐渐暖了飞燕还乡春天来了回忆少年那时无忧无虑无杂想但却无梦想静思青春现况忧心忡忡...
    墙角魅力阅读 259评论 0 1