陈银山 发表于 2018-9-13 10:12:09

oracle存储过程的简单学习1

  1.普通的存储过程
  eg.
  create or replace procedure proctest1
  is
  begin
  dbms_output.put_line('my fisrt proctest1 is beginning ....');
  end;
  /
  --执行存储过程--报无效的SQL错误
  --execute proctest1();
  --调用存储过程
  call proctest1();
  ☆说明:
  1.在sql的执行窗口中只能调用"call proctest1();",这样执行就是把“call proctest1()”
  当成一个SQL语句,而execute proctest1();不是一个SQL语句,是一个执行体,执行体调用必须
  在命令窗口,把这句话当成一个整体,也就是plsql块,但是,要在sql窗口中执行也可以,这样调用:
  begin
  proctest1;
  end;
  /
  2.传入带参数的存储过程
  create or replace procedure proctest2(tempId in emp.empno%TYPE)
  is
  nameValue emp.ename%TYPE;
  begin
  select ename into nameValue from emp where emp.empno = tempId;
  dbms_output.put_line(nameValue);
  end;
  /
  --执行存储过程--报:ORA-00900:无效的SQL语句
  execute proctest2(7934);
  --调用存储过程
  call proctest2(7934);
  3.带返回值的存储过程
  create or replace procedure proctest3(tempId in emp.empno%TYPE,tempName out emp.ename%TYPE)
  is
  nameValue emp.ename%TYPE;
  begin
  select ename into nameValue from emp where emp.empno = tempId;
  tempName := nameValue;
  end;
  --调用存储过程
  declare name1 emp.ename%TYPE;
  begin
  proctest3(7934,name1);
  dbms_output.put_line('name: ' || name1);
  end;
  /
  ===========================================
  存储过程其实就是能完成一定操作的一组SQL语句集,只不过这组语句是放在数据库中的。
  第一、大大提高效率。存储过程本身的执行速度非常快,而且,调用存储过程可以大大减少同数据库的交互次数。
  第二、提高安全性。假如将SQL语句混合在代码中,一旦代码失密,同时也就意味着库结构失密。
  第三、有利于SQL语句的重用。
  1.存储过程的最简单写法
  eg1.
  create or replace procedure p_test1
  is
  begin
  null;
  end;
  /
  --调用
  call p_test1();
  eg.2
  create or replace procedure p_test2(
  param1 varchar2,
  param2 out varchar2,
  param3 in out varchar2
  )
  as
  v_name varchar2(20);
  begin
  v_name := 'tom';
  param3 := v_name;
  dbms_output.put_line('param3: ' || param3);
  end;
  --调用
  declare name1 varchar2(20);
  begin
  p_test2('tom',name1,name1);
  dbms_output.put_line('name: ' || name1);
  end;
  /
  说明:
  1. CREATE OR REPLACE PROCEDURE test1 是一个SQL语句通知Oracle数据库去创建一个叫做test1存储过程, 如果存在就覆盖它;
  如果没有or replace语句,则仅仅是新建一个存储过程。如果系统存在该存储过程,则会报错。
  Create or replace procedure 如果系统中没有此存储过程就新建一个,
  如果系统中有此存储过程则把原来删除掉,重新创建一个存储过程。
  2. IS关键词表明后面将跟随一个PL/SQL体。
  3. BEGIN关键词表明PL/SQL体的开始。
  4. NULL PL/SQL语句表明什么事都不做,这句不能删去,因为PL/SQL体中至少需要有一句;
  5. END关键词表明PL/SQL体的结束
  6. IN 表示输入参数,按值传递方式。
  7. OUT 表示输出参数,可以理解为按引用传递方式。可以作为存储过程的输出结果,供外部调用者使用。
  8. IN OUT 即可作输入参数,也可作输出参数。
  9. 参数的数据类型只需要指明类型名即可,不需要指定宽度。 参数的宽度由外部调用者决定。
  10. 变量声明块:紧跟着的as (is )关键字,可以理解为pl/sql的declare关键字,用于声明变量。
  变量声明块用于声明该存储过程需要用到的变量,它的作用域为该存储过程。
  另外这里声明的变量必须指定宽度。遵循PL/SQL的变量声明规范。
  11. 过程语句块:从begin 关键字开始为过程的语句块。存储过程的具体逻辑在这里来实现。
  12. 异常处理块:关键字为exception ,为处理语句产生的异常。该部分为可选
  13. 结束块:由end关键字结果。
  ===================================================================================
  1.存储过程的参数传递方式
  存储过程的参数传递有三种方式:IN,OUT,IN OUT
  IN按值传递,并且它不允许在存储过程中被重新赋值。如果存储过程的参数没有指定参数传递类型,默认为IN。
  eg1.
  create or replace procedure p_test3(
  param1 varchar2,
  param2 out varchar2,
  param3 in out varchar2
  )
  as
  v_name varchar2(20);
  begin
  param1 := 'tom';
  param2 := 'jerry';
  v_name := 'hanchao';
  param3 := v_name;
  dbms_output.put_line('param3:' || param3);
  dbms_output.put_line('param2:' || param2);
  end;
  --编译就会报错,错误如下
  PROCEDURE SCOTT.P_TEST3 编译错误
  错误:PLS-00363: 表达式 'PARAM1' 不能用作赋值目标
  行:9
  文本:param1 := 'tom';
  错误:PL/SQL: Statement ignored
  行:9
  文本:param1 := 'tom';
  说明:这一点和其他高级语言都不同。它相当于java在参数前面加上final关键字了。
  eg2.
  create or replace procedure p_test4(
  param1 varchar2,
  param2 out varchar2,
  param3 in out varchar2
  )
  as
  v_name varchar2(20);
  begin
  -- param1 := 'tom';
  --param2 := 'jerry';
  v_name := 'hanchao';
  param3 := v_name;
  dbms_output.put_line('param3:' || param3);
  dbms_output.put_line('param2:' || param2);
  end;
  --注释掉: param1 := 'tom'; 编译通过,→ 调用
  declare p_name varchar2(20) := 'alax';
  p_name2 varchar2(20);
  begin
  p_test4('tom',p_name,p_name2);
  dbms_output.put_line('param2:' || p_name);
  end;
  说明:OUT 参数:作为输出参数,需要注意,当一个参数被指定为OUT类型时,
  就算在调用存储过程之前对该参数进行了赋值,在存储过程中该参数的值仍然是null.
  对于IN参数,其宽度是由外部决定。
  对于OUT 和IN OUT 参数,其宽度是由存储过程内部决定。
  因此,在写存储过程时,对参数的宽度进行说明是非常有必要的,最明智的方法就是参数的数据类型使用%type。这样双方就达成了一致。
  →→ 具体见下面的链接。
  2.参数的默认值:存储过程的参数可以设置默认值
  可以通过default 关键字为存储过程的参数指定默认值。在对存储过程调用时,就可以省略默认值。
  需要注意的是:默认值仅仅支持IN传输类型的参数。OUT 和 IN OUT不能指定默认值
  eg1.
  create or replace procedure p_test5(
  p1 varchar2,
  p2 varchar2 default 'xiweiyuan')
  as
  begin
  dbms_output.put_line('p1:' || p1);
  dbms_output.put_line('p2:' || p2);
  end;
  --调用
  call p_test5('hanchao');
  eg2.
  create or replace procedure p_test6(
  p1 varchar2 default 'xiweiyuan',
  p2 varchar2)
  as
  begin
  dbms_output.put_line('p1:' || p1);
  dbms_output.put_line('p2:' || p2);
  end;
  -- 调用
  call p_test6('hanchao');-- 会报错 → 对于默认参数不是排在组后的情况,应该这么去调用
  call p_test6(p2 => 'hanchao');
  3.存储过程的内部块:存储过程的结构,语句块由begin开始,以end结束。这些块是可以嵌套。在语句块中可以嵌套任何以下的块。
  Declare … begin … exception … end;
  create or replace procedure innerBlock(p1 varchar2)
  as
  v1 varchar2(10) := 'out1';
  begin
  dbms_output.put_line('v1:' || v1);
  dbms_output.put_line('p1:' || p1);
  declare inner1 varchar2(10);
  begin
  inner1 := 'inner1';
  dbms_output.put_line('inner1:' || inner1);
  declare inner2 varchar2(10);
  begin
  inner2 := 'inner2';
  dbms_output.put_line('inner2:' || inner2);
  end;
  exception
  when others then
  null;
  end;
  end;
  -- 调用存储过程
  call innerBlock('p1');
  您可以参考的地址,本文的一部分内容来自于这篇文章

页: [1]
查看完整版本: oracle存储过程的简单学习1