Oracle PLSQL 学习笔记摘要



 
--------
关注的重点内容:

1、PL/SQL 
2、PL/SQL程序结构
3、变量与数据类型
4、PL/SQL控制语句
5、PL/SQL游标
6、HANDLE EXCEPTION 
7、SUB PROGRAM
8、PACKAGE
9、TRIGGER

2,3,4,5,7重点内容


一、常见的访问oracle的技术
 1.1 PL/SQL   过程化SQL(存储过程)
 1.2 PRO*C/C++  使用c或者c++语言访问oracle数据库
 1.3 ODBC/ADO    VC中访问数据库的技术
 1.4 OCI   ORACLE底层的连接接口
 1.5 JDBC/SQLJ   JAVA访问数据库的技术




PL/SQL 实在标准SQL基础上增加了过程花处理的语言
ORACLE客户端工具访问oracle服务器的操作语言
oracle对SQL的补充

BEGIN
 IF TO_CHAR(SYSDATE,'DAY') ='Monday' THEN
  pay_for_hamburgers;
 ELSE
  borrow_hamburger_money;
 END IF;
END;

PL/SQL
 结构化模块化编程
 良好的可移植性
 良好的可维护性
 提升系统性能----批量处理
 
 不便于向异构数据库移植应用程序
 
 第四代语言
 只管做什么,不管怎么做
 缺少过程与控制语句
 无算法描述能力
 

二、PLSQL对SQL进行了扩展
 2.1 变量和类型
 2.2、控制结构
 2.3、过程与函数
 2.4、对象类型与方法
 
三、PLSQL的程序结构
 declare
 /*声明区  申明区
   定义变量 定义类型
 */
 --这是单行注释
 
 begin
 /*执行区 
   执行SQL语句或者PLSQL语句的*/
   
 exception --例外
 /*异常处理区
   处理正常流程之外的一些代码
 */
 end;
四、第一个PL/SQL程序

 set serverouput on 
 
 begin 
  update ....;
  commit;
  dbms_output.put_line('hello plsql');
 end;
 /  --执行 


 select count(*) from s_emp;  ---sql语句直接从客户端发送到sql执行器 
 
 PLSQL语句块  整个被发到给服务器上的过程性语句执行器。
 过程性语句由PL/SQL引擎处理
 PL/SQL语句块中的SQL语句由PLSQL引擎发给SQL执行器。
 
五、开发环境
 sqlplus  命令行下的开发工具
 sqldeveloper 图形化的开发工具 

六、变量 
 6.1 如何定义变量 
  在声明区定义变量
  变量名  类型;
 
 6.2 sql中的数据类型 
     number 
  varchar2(n)
  date 
  
declare
 var_id  number;
 var_name varchar2(30);
begin
 /*给变量赋值*/
 var_id:=100;
 var_name:='test'; --:=代表赋值
 dbms_output.put_line(var_id||':'||var_name);
end;  

 6.3 变量的修饰 
    constant   类型      not null
 
 constant类型---必须初始化,不能修改
 not null 非空必须初始化一个值
 
 declare
  var_id   constant number:=1;
  var_name varchar2(30) not null:='a';--值可改
 begin
  --var_id:=100;
  var_name:='test';
  dbms_output.put_line(var_id||'--'||var_name);
 end;
 
 constant和not null修饰的变量必须赋初值
 也就意味着一个变量定义之后不赋值默认值为NULL。
 

 6.4 使用sql语句对变量进行赋值(相当于把硬盘上的数据倒腾到PLSQL所操作的内存中了)
declare
 var_name    varchar2(30);
 var_salary  number;
 var_id      number:=1;
begin
 select first_name,salary into var_name,var_salary 
 from s_emp where id=var_id;
 dbms_output.put_line(var_name||':'||var_salary);
end; 

七、PLSQL中可以使用的数据类型 
 7.1 标量类型 
 number 
 varchar2(n)
 char(n)
 date

 binary_integer
 boolean
7.2 复合类型 
    record 记录类型
 table 表类型
 cursor  游标类型 
7.3 参考类型
 ref 类型 
7.4 大类型(存储数据路径)
 BLOB 大二进制 0-4g
 CLOB 大字符类型 0-4g
 BFILE 文件类型

八、plsql中的类型的使用
 8.1 boolean 和 binary_integer的使用
 declare
  var_f boolean;
  var_count binary_integer;
 begin
  var_f:=true;
  --var_f:=false;
  var_count:=1000;
  if  var_f  then
   dbms_output.put_line(var_count);
  end if;
 end;
 8.2 获得字段对应类型
 8.2.1 定义两个变量  分别和s_emp表中的id 和 first_name 字段的类型相同。
 并且使用sql语句把id=1的值赋值给这两个变量
 declare
  var_id    number(7):=1;
  var_name  varchar2(25);
 begin 
  select id,first_name into var_id,var_name from s_emp where id = var_id;
  dbms_output.put_line(var_id||':'||var_name);
 end;
 
 8.2.2 使用  表名.字段名%type   
 可以获得字段对应的类型
 declare
  var_id    s_emp.id%type:=1;
  var_name  varchar2(25);
 begin 
  select id,first_name into var_id,var_name from s_emp where id = var_id;
  dbms_output.put_line(var_id||':'||var_name);
 end; 
 
 
 8.2.3 使用record类型
     8.2.3.1 语法:
  record类型 相当于 struct 类型
 
  type record 类型名  is record(
   字段名  类型,
   字段名  类型,
   字段名  类型 
  );
  8.2.3.2 举例 
  把id  first_name salary包装成一个类型
  
  declare
   /*首先定义一个record类型*/
   type emptype is record(
    id    s_emp.id%type,
    first_name      s_emp.first_name%type,
    salary    s_emp.salary%type
   );
   /*使用类型定义变量*/
   var_emp  emptype;
  begin
   select id,first_name,salary into var_emp from s_emp where id = 1;
   dbms_output.put_line(var_emp.id||':'||var_emp.first_name||':'||var_emp.salary);
  end;
 
  8.2.3.3 如果查询的字段数少于记录类型字段数
  declare
   type emptype is record(
    id     s_emp.id%type,
    first_name      s_emp.first_name%type,
    salary    s_emp.salary%type
   );
   var_emp  emptype;
  begin
   select id,salary into var_emp.id,var_emp.salary from s_emp where id = 2;
   dbms_output.put_line(var_emp.id||':'||var_emp.salary); 
  end;
  
  8.2.3.4 记录类型的变量赋值
  能不能把一个结构体
  declare
   type emptype is record(
    id     s_emp.id%type,
    first_name      s_emp.first_name%type,
    salary    s_emp.salary%type
   );
   var_emp  emptype;
   var_emp2  emptype;
  begin
   select id,first_name,salary into var_emp2 from s_emp where id = 2;
   --var_emp:=var_emp2;---整体复制赋值
   /*选择某些字段赋值   这样只要名字*/
   var_emp.first_name:=var_emp2.first_name;
   var_emp.id:=var_emp2.id;
   var_emp.salary:=var_emp2.salary;
   
   dbms_output.put_line(var_emp.id||':'||var_emp.first_name||':'||var_emp.salary); 
   dbms_output.put_line(var_emp2.id||':'||var_emp2.first_name||':'||var_emp2.salary); 
  end;
  
 8.2.4 思考如何把一个表的所有字段包装成一个记录类型呢?
  表名%rowtype  获得表的一行对应的类型  字段名和表头的顺序一模一样  不用担心弄混。
  
  这个类型实际上就是字段名和字段顺序完全和表头相同的记录类型。
  
  
  s_dept%rowtype 意味着取的部门表的一行
  s_emp%rowtype 意味着获取员工标的一行 
  
  把s_emp表中 id=1所有数据放入一个记录类型的变量中  输出id  first_name salary 
  
  declare
   var_emp  s_emp%rowtype;
   
  begin
   select id,first_name,salary into var_emp.id,var_emp.first_name,var_emp.salary from s_emp where id=1;
   dbms_output.put_line(var_emp.id||':'||var_emp.first_name||':'||var_emp.salary);
  end;
 
  ------
  
  declare
   var_emp  s_emp%rowtype;
   
  begin
   select * into var_emp from s_emp where id=1;
   dbms_output.put_line(var_emp.id||':'||var_emp.first_name||':'||var_emp.salary);
  end;
 
 8.2.5 table类型 相当于C的数组类型 
  8.2.5.1  table类型的语法
  type 表类型名  is table of 元素类型 index by binary_integer;
  
  8.2.5.2 使用table类型的变量
  把id = 1 或者id = 3 或者id=7 的工资放入一个table类型的变量中
  
  declare 
   /*定义table类型*/
   type numstype is table of s_emp.id%type index by binary_integer;
   /*使用类型定义变量*/
   var_nums  numstype;
   /*存储下标的变量*/--二进制整数
   var_ind  binary_integer;  
  begin
   var_nums(11):=300;
   select salary into var_nums(1) from s_emp where id=1;
   select salary into var_nums(2) from s_emp where id=3;
   select salary into var_nums(3) from s_emp where id=7;
   var_ind:=1;
   dbms_output.put_line(var_nums(var_ind));
   var_ind:=var_ind+1;
   dbms_output.put_line(var_nums(var_ind));
   var_ind:=var_ind+1;
   dbms_output.put_line(var_nums(var_ind));  
  end;
  
  8.2.5.3 下标不连续时,如何遍历table中的数据  非常高级的思想  
   迭代器思想
   first() 得到第一个元素对应的下标
   next(n) 根据一个元素的下标n得到下一个元素的下标
   last()  得到最后一个元素的下标
   
  declare 
   /*定义table类型*/
   type numstype is table of s_emp.id%type index by binary_integer;
   /*使用类型定义变量*/
   var_nums  numstype;
   /*存储下标的变量*/--二进制整数
   var_ind  binary_integer;  
  begin
   var_nums(11):=300;
   select salary into var_nums(1) from s_emp where id=1;
   select salary into var_nums(2) from s_emp where id=3;
   select salary into var_nums(3) from s_emp where id=7;
   var_ind:=var_nums.first();
   dbms_output.put_line(var_nums(var_ind));
   var_ind:=var_nums.next(var_ind);
   
   dbms_output.put_line(var_nums(var_ind));
   var_ind:=var_ind+1;
   dbms_output.put_line(var_nums(var_ind));  
  end; 
  
九、变量的作用域和可见性
  declare
   var_m  number:=10000;
  begin
   declare
    var_m  number:=100;
   begin
    /*局部区可以访问全局的数据*/
    dbms_output.put_line(var_m);---100,但是想访问全局的,怎么办呢?
   end;
   /*全局区不能访问局部区*/
  end;
  
  <<outerblock>>
  
  declare
   var_m  number:=10000;
  begin
   declare
    var_m  number:=100;
   begin
    /*局部区可以访问全局的数据*/
    dbms_output.put_line(var_m);---100,但是想访问全局的,怎么办呢?
    dbms_output.put_line(outerblock.var_m);
   end;
   /*全局区不能访问局部区*/
  end;
十、PLSQL中的控制语句
  10.1 分支语句
 if a>b then
 
 end if;
 
 ------

 if a>b then 
 
 else 
 
 end if;
 ---
 if a>b then
 
 elsif a>c then 
 
 elsif a>d then 
 
 else 
 
 end if;
 ----
 
 
 ---
 
 10.1.2 举例
   10.1.2.1 定义3个整数变量 给这3个变量赋值  输出这3个变量的最大值
   declare
  a number;
  b number;
  c number;
   begin
  if a>b then 
   if b>c then 
   a 
   elsif a>c then 
   a 
   elseif a<c then 
   c 
   end if;
  else--a<b
   if b>c then 
    b 
    else 
    c
   end if;
  end if;
   end;
   
   
   ------
   declare
  var_a number;
  var_b number;
  var_c number;
  var_max number;
   begin
  var_a:=&var_a;
  var_b:=&var_b;
  var_c:=&var_c;
  var_max:=var_c;
  if var_max < var_a then 
   var_max:=var_a;
  end if;
  if var_max < var_b then 
   var_max:=var_b;
  end if;
  dbms_output.put_line(var_max);
  
   end;
   
   10.1.2.2  NULL值的判断 
   declare
  var_a number;
  var_b  number;
  
   begin
  if var_a<var_b then 
   dbms_output.put_line('var_a<var_b');
  elsif var_a >var_b then 
   dbms_output.put_line('var_a>var_b');
  elsif var_a=var_b then 
   dbms_output.put_line('var_a=var_b');
  elsif var_a is null and var_b is null then  
   dbms_output.put_line('var_a is null and var_b is null');
  else
   NULL;--这是PLSQL中的NULL空语句
  end if;
   end;
  10.2 循环语句
 10.2.1 简单循环
  loop
   /*循环执行的代码或者语句*/
  end loop;
 10.2.2 如何退出当前循环?
 
  exit when 循环的结束条件;---死于非命
  
  /*可以带有遗言的消亡*/
  if 退出条件 then 
   exit;
  end if;
 10.2.3 使用简单循环从1输出到10
  declare
   var_num number:=1;
  begin
   loop 
    dbms_output.put_line(var_num);
    var_num:=var_num+1;
    exit when var_num=11;
   end loop;
  end;
  
  ----
  
  declare
   var_num number:=1;
  begin
   loop 
    dbms_output.put_line(var_num);
    var_num:=var_num+1;
    if  var_num >10 then 
     dbms_output.put_line('loop over');
     exit;
    end if;
   end loop;
  end;
  
 10.2.4 while循环 
  10.2.4.1 语法 
  while (满足条件进入)循环条件  loop 
   /*循环代码*/
   
  end loop;
 10.2.5 使用while循环输出1到10 
  declare
   var_i  number:=1;
  begin 
   while var_i<11 loop
    dbms_output.put_line(var_i);
    var_i:=var_i+1;
   end loop;
  end;
    10.2.6 for循环(智能循环)
  for 变量名 in a..b 
  /*循环代码   变量在循环中不允许修改 */
  end loop;
 10.2.7 使用for循环输出1到10 
 declare
  var_i number:=1;
 begin 
  for var_i in 1..10 loop 
   dbms_output.put_line(var_i);
  end loop;
 end;
  
  备注:var_i中的值不能更改。
   10.2.8 使用for循环输出10到1(reverse 翻转   关键字)
   begin 
 for var_i in reverse 1..10 loop 
  dbms_output.put_line(var_i);
 end loop;
   end;
  
  10.3 goto语句
 10.3.1 语法 
 goto  标签名;  <<标签名>>
 10.3.2 使用goto语句 输出1到10达到一个循环的效果。
 declare
  var_i  number:=1;
 begin
  <<myloop>>
  if var_i < 11 then 
   dbms_output.put_line(var_i);
   var_i:=var_i+1;
   goto myloop; 
  end if;
 end;
 10.3.3. 退出多重循环
 begin 
  <<myloop>>  
  for a in 1..4 loop
   for b in 1..4 loop 
    dbms_output.put_line(b);
    if b=2 then 
     exit myloop;
    end if;
   end loop;
  end loop;

 end;
 
 
 ---注意两段的区别,
  begin 
  for a in 1..4 loop
   for b in 1..4 loop 
    dbms_output.put_line(b);
    if b=2 then 
     goto myloop;
    end if;
   end loop;
  end loop;
  <<myloop>>
  NULL;--空语句
 end;
 
----
一、sql在PLSQL中的使用
1.1 select语句 要和into结合使用,不允许在PLSQL中使用。
 select first_name,salary into var_name,var_sal from s_emp where id=1;

1.2 dml(insert,update ,delete)
 tcl(commit,rollback,savepoint)
 这些语句可以直接在plsql中使用

1.3 ddl(create,drop,alter)不能直接在plsql中使用,需要使用动态sql。

二、动态sql

2.1 动态sql的概念   --- SQL 语句在程序执行的过程中可以发生改变。

 静态sql,sql语句在程序执行的过程中不能改变。下例就是静态sql但是不能执行提示
2.2 DDL的动态SQL 
 
 declare
  sqlstr  varchar2(100);
 begin
  sqlstr:='create table testdsql(id number primary key)';
  sqlstr:=substr(sqlstr,1,length(sqlstr)-1); 
  sqlstr:=sqlstr||','||'name varchar2(30))';
  dbms_output.put_line(sqlstr);
  execute immediate sqlstr;
 end;
  
2.3  DML的动态sql
 'insert into testdsql values(1,''test'')'
 
 declare
  sqlstr  varchar2(100);
 begin
  sqlstr:='insert into testdsql values(1,''test'')';
  dbms_output.put_line(sqlstr);
  execute immediate sqlstr;
  commit;
 end;

-----------上面的sqlstr信息也写死了。
 
   declare
  sqlstr  varchar2(100);
  var_id  number:=2;
  var_name varchar2(30):='test2';
 begin
  sqlstr:='insert into testdsql values(:b0,:b1)';--/*:b0,:b1 占位符*/
  dbms_output.put_line(sqlstr);
  
  execute immediate sqlstr using var_id,var_name;
  commit;
 end;
 
 2.4 select语句的动态sql 在参考游标中完成 

三、游标
 3.1 概念 
 用来处理多行数据的一个数据结构 
 
 3.2 使用游标的步骤:
   1 声明游标
 declare 
  cursor 游标名 is select 语句; 
   游标本质对应一个select语句,select语句的返回内容都装到游标中。
   2 打开游标 
    open  游标名;
 
   3 提取数据
 fetch 游标名 into 变量;
 
   4 关闭游标 
    close 游标名
 
  3.3 把s_emp表中所有的数据放入一个游标中
  declare
 cursor cs is select * from s_emp;
 var_a cs%rowtype;
  begin
 open cs;
 fetch cs into var_a;
 dbms_output.put_line(var_a.id||':'||var_a.first_name);
 fetch cs into var_a;
 dbms_output.put_line(var_a.id||':'||var_a.first_name);
 fetch cs into var_a;
 dbms_output.put_line(var_a.id||':'||var_a.first_name);
 close cs;
  end;
 ------
 3.4 通过循环  思考  如何提取游标中的所有的数据。 
 游标的属性 ---%NOTFOUND
 游标名%found  在提取数据时提取到新数据就返回真,提取不到新数据就返回假
     游标没有打开时,使用found属性就返回非法游标,打开但是没有fetch
     则返回NULL.
 游标名%notfound 在提取数据时,提取到新数据就返回假,提取不到新数据就返回真。
     游标没有打开时,使用notfound属性就返回非法游标,打开但是没有fetch
     则返回NULL. 
  ORA-1001 非法游标
 游标名%isopen  游标是否处于打开状态
     打开就返回真关闭返回假
     打开的游标再打开
     关闭的游标不能再关闭
 游标名%rowcount 游标指针偏移量    
 
 

  
 3.5 使用简单循环  结合notfound属性遍历游标
 
   declare
 cursor cs is select * from s_emp;
 var_a cs%rowtype;
  begin
 open cs;
 loop
  fetch cs into var_a;
  exit when cs%NOTFOUND;
  dbms_output.put_line(var_a.id||':'||var_a.first_name);
  
 end loop;
 close cs;
  end;
  
  3.6 使用while循环结合found属性遍历游标
  declare 
  cursor  cs is select * from s_emp;
  var_a cs%rowtype;
  begin 
 open cs;
 fetch cs into var_a;---一定要深刻理解为啥要加此行。理解%found
 while cs%found loop
  fetch cs into var_a;
  dbms_output.put_line(var_a.id||':'||var_a.first_name);
 end loop;
 close cs;
  end;
  
 
 3.7 for循环遍历游标
 
  declare 
  cursor  cs is select * from s_emp;
  begin 
 for var_a in cs loop  ----直接把游标看成一个区间
  dbms_output.put_line(var_a.id||':'||var_a.first_name);
 end loop;
  end;
  
  3.8 带参游标
  
  plsql中的参数 不能加任何长度修饰
  但可以使用%type 
  参数名不要和字段名重名
  
  
  显示id>10的记录。
  
  declare 
  cursor  cs(var_id s_emp.id%type) is select * from s_emp where id > var_id;
  
  begin 
 for var_a in cs(10) loop  ----直接把游标看成一个区间
  dbms_output.put_line(var_a.id||':'||var_a.first_name);
 end loop;
  end;
  
 
  declare 
  cursor  cs(var_id s_emp.id%type) is select * from s_emp where id > var_id;
  var_a s_emp%rowtype;
  begin 
 open cs(10);
 loop 
  fetch cs into var_a;
  exit when cs%NOTFOUND;
  dbms_output.put_line(var_a.id||':'||var_a.first_name);
 end loop;
 close cs;
  end;
  
  3.9 参考游标(引用游标)
    游标对应的SQL语句是一条字符串
 
 3.9.1 定义参考游标类型:
 type  myrefcursor is ref cursor;
 3.9.2 使用参考游标类型定义游标变量
 empcursor myrefcursor;
 3.9.3 打开游标时 关联到字符串
 open empcursor for sqlstr;
 
 declare
  sqlstr  varchar2(100):='select * from s_emp';
  type myrefcursor is ref cursor;
  empcursor myrefcursor;
  var_emp  s_emp%rowtype;
 begin
  /*关联游标 到 字符串*/
  open empcursor for sqlstr;
  loop 
   fetch empcursor into var_emp;
   exit when empcursor%notfound;
   dbms_output.put_line(var_emp.id||':'||var_emp.first_name);
  end loop;
  close empcursor;
 end;
  
  ---------类似带参游标
   declare
  sqlstr  varchar2(100):='select * from s_emp where id > :b0';
  type myrefcursor is ref cursor;
  empcursor myrefcursor;
  var_emp  s_emp%rowtype;
  var_id  s_emp.id%type:=15;---新增 
 begin
  /*关联游标 到 字符串*/
  open empcursor for sqlstr using var_id;
  loop 
   fetch empcursor into var_emp;
   exit when empcursor%notfound;
   dbms_output.put_line(var_emp.id||':'||var_emp.first_name);
  end loop;
  close empcursor;
 end;
 
 
四、PLSQL中的异常
  4.1 系统提供的异常以及处理
 declare
  var_name s_emp.first_name%type;
  var_id   s_emp.id%type:=-1;
 begin
  select first_name into var_name from s_emp where id = var_id;
  dbms_output.put_line(var_name);
 exception
  when no_data_found then
  dbms_output.put_line('MYPROCESS'||SQLCODE||':'||SQLERRM);
  insert into logtable values(sqlcode,sysdate);
  when too_many_rows then
  dbms_output.put_line('too many emps');
  when others then 
  dbms_output.put_line('other exception');
 end;

  4.2 用户自定义异常
 4.2.1 根据实际情况定义异常
 4.2.2 根据条件抛出异常
 4.2.3 异常捕获
 4.2.4 处理异常
 
 declare
  too_many_emp exception;
 begin 
  if 1=1 then
   raise too_many_emp;
  end if;
  dbms_output.put_line('app continue!');
 exception
  when too_many_emp then 
   dbms_output.put_line('catch emp exceptiono');
 end;

五、存储过程
 
 5.1 对一组sql语句起的一个逻辑名
 5.2 如何建立存储过程
 
 create or replace procedure 存储过程名(参数列表)
 is 
 /*不允许出现declare,is充当了declare*/
 
 begin
 
 end;
 
 5.3 设计一个存储过程 传入两个整数参数 输出两个参数的最大值
 create or replace procedure maxvar(var_a number,var_b number)
 is 
 begin 
  if var_a > var_b then 
   dbms_output.put_line(var_a);
  else
   dbms_output.put_line(var_b);
  end if;
 end;

 
 5.4 查看并调用存储过程
  
SQL> desc maxvar   
PROCEDURE maxvar
 Argument Name   Type   In/Out Default?
 ------------------------------ ----------------------- ------ --------
 VAR_A    NUMBER   IN
 VAR_B    NUMBER   IN

参数模式:
 in 负责给存储过程传入值 
 out 负责给存储过程传出值
 in out 既负责传入又负责传出值

参数的默认值
 create or replace procedure maxvar(var_a number,var_b number:=100)
 is 
 begin 
  if var_a > var_b then 
   dbms_output.put_line(var_a);
  else
   dbms_output.put_line(var_b);
  end if;
 end; 
 5.5 调用存储过程
 begin
  maxvar(100,200);
 end;

 如何查看存储过程的内容??
 desc user_source
 select text from user_source where name = 'MAXVAR';
 
 5.6 写一个存储过程 传入三个整数参数
 输出前两个参数的最大值 并把两个参数的和放入第三个参数中
 
 create or replace procedure getmaxandsum(var_x in number,var_y in number,var_z out number)
 is 
 begin
  if var_x < var_y then 
   dbms_output.put_line(var_y);
  else
   dbms_output.put_line(var_x);
  end if;
  
  var_z:=var_x+var_y;
 end;

 declare
  var_z number:=0;
 begin
  getmaxandsum(100,200,var_z);
  dbms_output.put_line(var_z);
 end;
 
    5.7 设计一个存储过程 有两个整数参数
 输出这两个参数的最大值 然后把两个参数的和存入第二个参数中
 
 create or replace procedure getmaxsum(var_x in number,var_y in  out number)
 is 
 
 begin
  if var_x<var_y then 
   dbms_output.put_line(var_y);
  else
   dbms_output.put_line(var_x);
  end if;
  var_y:=var_x+var_y;
  dbms_output.put_line(var_y);
 end;
  
 declare
  var_y number:=200;
 begin
  getmaxsum(100,var_y);
 end;
 
   5.8 设计一个存储过程 有两个整数参数 第一个参数是一个传入的整数,
   第二个参数负责返回1 加到第一个参数的和
   
   create or replace procedure getnum(x in number,y in out number)
   is
   begin
  for i in 1..x loop
   y:=i+y;
  end loop;
   end;
   /
   declare
  var_y   number:=0;
   begin
  getnum(10,var_y);
  dbms_output.put_line(var_y);
   end;
   
六、函数
 函数和存储过程的不同:
 6.1 关键字不同 procedure  function
 6.2 函数有返回值和返回值类型
  存储过程没有
 6.3 调用方式不同 存储过程可以直接在PLSQL中调用
      函数必须组成表达式
   
 写一个函数 传入两个整数参数 返回两个整数参数的最大值。
 create or replace function fungetmax(x in number,y in number) return number 
 is 
 begin
  if x<y then 
   return y;
  end if;
   return x;
 end;
 
 declare
  var_res number;
 begin 
  var_res:=fungetmax(100,200);
  dbms_output.put_line(var_res);
 end;
 
---plsql中显示错误
   show errors;
   
   设计一个函数 传入两个整数参数  返回这两个整数参数的最大值,还要把两个参数的和放入第二个参数中
   
   create or replace function fungetmaxandsum(x in number,y in out number) return number
   is 
  temp number;
   begin
  temp:=x+y;
  dbms_output.put_line(temp);
  if x < y then 
   return y;
  else 
   return x;
  end if;

   end;
   
   declare
  var_z number:=200;
   begin 
  var_z:=fungetmaxandsum(100,var_z);
  dbms_output.put_line('return number:'||var_z);
   end;
   
七、包package 
 7.1 概念
 组织相关数据的一种逻辑结构名
 
 7.2 系统提供的包
desc dbms_output
 dbms_output.put_line('hello world');
 
 使用包中的数据需要在数据前加包名。
 
desc dbms_random;
 
 select dbms_random.value(1,100) from dual;
 select trunc(dbms_random.value(1,100)) from dual;

 /*定时调用存储过程*/
 desc dbms_job;
  dbms_job.submit(job out binary_integer
  what in varchar2,
  next_date date,
  interval varchar2
  );

 submit的含义是把定时任务提交给系统,系统会分配一个任务编号放入第一个参数,
 what要定时调用的存储过程 写到第二个参数中
 next_date 第一次调用的时间 
 interval 第二次调用的时间
 
 dbms_job.run(job in binary_integer);
 让任务编号为job的定时任务执行起来。
 
 dbms_job.remove(job in binary_integer);
 删除编号为job的定时任务
 7.3 定时调用一个存储过程
  7.3.1 建立一张表
  create table testjob(id number primary key,name varchar2(30));
  
  7.3.2 为这张表建立一个索引序列
  create sequence testjob_id;
  
  7.3.3 建立一个存储过程向表中插入一条数据
  
  create or replace procedure insert_job
  is 
  begin
   insert into testjob values(testjob_id.nextval,'testjob'||testjob_id.currval);
   commit;
  end;
  
  7.3.4 使用dbms_job包定时调用存储过程
  
  declare
   jobno binary_integer;
  begin
   dbms_job.submit(jobno,'insert_job();',sysdate,'sysdate+1/1440');---注意这里的分号是重点要不不执行。
   dbms_output.put_line('jobno='||jobno);
   dbms_job.run(jobno);
  end;
  7.3.5 select job from user_jobs;
  begin
   dbms_job.remove(1181);
  end;
  
--------------------------------------------
  
 unix,linux--->crontab的使用 
 
--------------------------------------------

 7.4 自定义包
  7.4.1 定义一个包的头文件
  C语言中声明函数,声明变量
  
  PLSQL:/*注意有is,end,没有begin*/---相当于C的头文件
  create or replace package mypack is 
   procedure getmax(x in number,y in number);
   function getmin(x number,y number)return number;
  end;
  7.4.2 写一个包的实现
  相当于C的实现文件
  create or replace package body mypack is 
   procedure getmax(x in number,y in number)
   is
   begin
    if x<y then 
     dbms_output.put_line(y);
    else 
     dbms_output.put_line(x);
    end if;
   end;
   function getmin(x number,y number)return number
   is 
   begin
    if x<y then 
     return x;
    else 
        return y;
    end if;
   end; 
  end;  
  
  访问包中的数据 需要在数据前加包名。
  declare
   var_x number:=1;
   var_y number:=2;
   var_res  number:=0;
  begin
   mypack.getmax(var_x,var_y);
   var_res:=mypack.getmin(var_x,var_y);
   dbms_output.put_line(var_res);
  end;
   
   ---------------------------------------------------------------
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值