zoukankan      html  css  js  c++  java
  • Oracle PL/SQL编程

    一、PL/SQL简介

      1、概念:PL/SQL是Oracle在标准SQL语言上的过程性扩展。

      2、优点和特性

    •   提高应用程序的运行性能
    •   提供模块化的程序设计功能
    •   允许定义标示符
    •   具有过程语言控制结构
    •   具备良好的兼容性
    •   处理运行错误

    二、PL/SQL语言基础

      1、编写PL/SQL应用程序时,只能嵌入select语句、DML语句和事务控制语句,不能嵌入DDL语句,DCL语句。

      2、PL/SQL块

      基本结构如下所示:

    1 declare 
    2 /*定义部分-变量、常量、游标、异常、例解*/
    3 begin
    4 /*执行部分-PL/SQL,SQL 语句*/
    5 exception
    6     /*异常处理部分-处理运行错误*/
    7 end;//块结束标志

      3、PL/SQL数据类型(常用)

    •   标量类型(常用char,varchar2,number,date,timestamp,boolean)
    •   属性类型(常用%type,%rowtype)
    •       其他record,table,varray

      4、注释:"--"单行注释,"/*...*/"多行注释

    三、PL/SQL控制结构

      1、条件分支语句

      用法如下所示:

     1 --示例一
     2 declare
     3  v_sal number(6,2);
     4 begin
     5   select sal into v_sal from scott.emp where ename=trim('&ename');
     6   if v_sal<2000 then
     7     update scott.emp set sal=v_sal+200 where ename=trim('&ename');
     8   end if;
     9 end;
    10 
    11 --示例二
    12 declare 
    13   v_dep number(6,2);
    14   v_sal number(6,2);
    15 begin
    16   select deptno,sal into v_dep,v_sal from scott.emp where ename=trim('&ename');
    17   if v_dep=10 then
    18      update scott.emp set sal=v_sal+200 where deptno=10;
    19   elsif v_dep=20 then
    20      update scott.emp set sal=v_sal+100 where deptno=20;
    21   else 
    22      update scott.emp set sal=v_sal+50 where deptno!=10 and deptno!=20;
    23   end if;
    24 end;

      2、case语句

      具体用法如下所示:

     1 --示例一
     2 declare 
     3      v_deptno scott.emp.deptno%type;
     4 begin
     5   v_deptno:=&deptno;
     6   case v_deptno
     7     when 10 then
     8       update scott.emp set comm=100 where deptno=v_deptno;
     9     when 20 then
    10       update scott.emp set comm=80 where deptno=v_deptno;
    11     when 30 then
    12       update scott.emp set comm=60 where deptno=v_deptno;
    13     else
    14       dbms_output.put_line('该部门不存在!');
    15    end case;
    16 end;
    17 
    18 --示例二
    19 declare 
    20    v_sal scott.emp.sal%type;
    21    v_ename scott.emp.ename%type;
    22 begin
    23   select ename,sal into v_ename,v_sal from scott.emp where empno=&empno;
    24   case
    25     when v_sal<2000 then
    26       update scott.emp set comm=100 where ename=v_ename;
    27     when v_sal<3000 then
    28       update scott.emp set comm=80 where ename=v_ename;
    29     when v_sal<4000 then
    30       update scott.emp set comm=50 where ename=v_ename; 
    31     end case;
    32 end;

      3、循环语句

      具体用法如下所示:

     1 --基本循环
     2 declare 
     3   i int:=1;
     4 begin
     5   loop   
     6     dbms_output .put_line(i);
     7     i:=i+1;
     8     exit when i=10;
     9   end loop;
    10 end;
    11 
    12--while循环
    13 declare 
    14   i int:=1;
    15 begin
    16   while i<=10 loop
    17     dbms_output.put_line(i);
    18     i:=i+1;
    19     end loop;
    20 end;
    21 
    22--for循环
    23 declare 25 begin
    26   for i in 1..10 loop
    27     dbms_output.put_line(i);
    28     end loop;
    29 end;

    四、异常处理

      1、分类:预定义异常,非预定义异常,自定义异常  

      2、常见预定义异常

    •   case_not_found:when子句中没包含必须的条件分支,又无else子句时触发。
    •   cursor_already_open:打开已打开的游标时触发。
    •   invalid_number:字符转换为数字失败时触发。
    •   too_many_rows:执行select into 子句时,返回超过一行触发。
    •   zero_divide:除数为0时触发。
    •   no_data_found:执行select into未返回行,或者引用了索引表未初始化元素时触发。

      具体用法如下所示:

     1 --预定义异常处理
     2 eclare 
     3     v_ename scott.emp.ename%type;
     4 begin
     5   select ename into v_ename from scott.emp where empno=&empno;
     6   dbms_output.put_line(v_ename);
     7   exception
     8     when no_data_found then
     9       dbms_output.put_line('员工号不存在');
    10 end;
    11 
    12 --自定义异常处理
    13 declare 
    14    e_integerity exception;--定义非预定义异常
    15    e_no_employee exception;--定义自定义异常
    16    pragma exception_init(e_integerity,-2291);--关联非预定义异常
    17 begin
    18    update scott.emp set deptno=40 where empno=-1;
    19       if sql%notfound then
    20         raise e_no_employee;--显示触发自定义异常
    21       end if;
    22    exception
    23       when e_integerity then
    24         dbms_output.put_line('该部门不存在!');
    25       when e_no_employee then
    26         dbms_output.put_line('该员工不存在!');
    27 end;

    五、游标(处理select语句返回的多行数据)

      (1)显示游标(查询结构超过一行)在PL/SQL块的声明部分申明,在执行部分或异常处理部分打开游标,提取数据,关闭游标。

      1、定义游标(declare cursor cursor_name is select_statement;)

      2、打开游标(open cursor_name;)

      3、提取数据

    1 --每次提取一行
    2 fetch cursot_name into variable1,variable2,..--variable :接收游标数据的变量
    3--每次提取多行
    4 .或 fetch cursor_name into bulk collect into collect1,collect2...--collect :接收游标结果的集合变量

      4、关闭游标(close cursor_name;)

      5、显示游标属性

    •   %isopen:判断游标是否打开,打开返回true,否则false;
    •   %found:是否从结果集中提取了数据。提取了数据返回true,否则false;
    •       %not found:与%found相反;
    •       rowcount:当前行数;

      具体用法如下所示:

     1 declare 
     2   cursor emp_cursor
     3 is
     4   select ename,sal from scott.emp where deptno=20;
     5   v_ename scott.emp.ename%type;
     6   v_sal scott.emp.sal%type;
     7 begin
     8   open emp_cursor;
     9   loop
    10     fetch emp_cursor into v_ename,v_sal;
    11     exit when emp_cursor%notfound;
    12     dbms_output.put_line(v_ename||':'||v_sal);
    13   end loop;
    14   close emp_cursor;
    15 end;
    16  
    17 --参数游标
    18 declare 
    19   cursor emp_cursor(cno number)
    20 is
    21   select ename,sal from scott.emp where deptno=cno;
    22   v_ename scott.emp.ename%type;
    23   v_sal scott.emp.sal%type;
    24 begin
    25   if not emp_cursor%isopen then
    26     
    27   open emp_cursor(10);
    28   end if;
    29   loop
    30     fetch emp_cursor into v_ename,v_sal;
    31     exit when emp_cursor%notfound;
    32     dbms_output.put_line(v_ename||':'||v_sal);
    33   end loop;
    34   close emp_cursor;
    35 end;
    36 
    37 --使用游标更新或删除数据
    38 declare 
    39   cursor emp_cursor
    40 is
    41   select ename,sal from scott.emp for update of sal;--在sal列上加上共享锁
    42   v_ename scott.emp.ename%type;
    43   v_sal scott.emp.sal%type;
    44 begin
    45   open emp_cursor;
    46   loop
    47     fetch emp_cursor into v_ename,v_sal;
    48     exit when emp_cursor%notfound;
    49     if v_sal<2500 then
    50       update scott.emp set sal=sal+150 where current of emp_cursor;
    51     end if;
    52   end loop;
    53   close emp_cursor;
    54 end;
    55 --游标的for循环语法
    56 for record_name in curso_name loop
    57     statement1;
    58     statement2;
    59 ...
    60 end loop;  --record_name:Oracle 隐式定义的记录变量名
    61 --游标的for循环
    62 declare 
    63   cursor emp_cursor
    64   is select ename from scott.emp where deptno=20;
    65 begin
    66   for o in emp_cursor loop
    67     dbms_output.put_line(''||emp_cursor%rowcount ||'员工'||o.ename);
    68     end loop;
    69 end;
    70 
    71 
    72 --不使用游标属性的for循环
    73 begin
    74   for o in (select ename from scott.emp where deptno=20)
    75    loop
    76      dbms_output.put_line(o.ename);
    77    end loop;
    78 end;
    79  
    80 select * from scott.emp;

      

  • 相关阅读:
    dtoi2680「SDOI2016」生成魔咒
    dtoi2679「SDOI2016」游戏
    dtoi2678「SDOI2016」数字配对
    dtoi2677「SDOI2016」储能表
    dtoi4545「HNOI2016」树
    dtoi4543「HNOI2016」最小公倍数
    dtoi4544「HNOI2016」网络
    dtoi4548「HNOI2016」大数
    ts定义数组对象
    RN项目ios本地模拟机无法加载本地图片的解决方案
  • 原文地址:https://www.cnblogs.com/yuchengping/p/3490930.html
Copyright © 2011-2022 走看看