Oracle(六)PL/SQL编程你知道多少

 

目录

概述:

什么是PL/SQL?

PL/SQL块的主要组成部分:

格式:

注意规范: 

 变量与数据类型

      声明变量:

     变量定义举例:

标量变量

复合类型的变量

条件语句

if...then(单分支)

if...then..else(双分支)

if...then ...elsif(多分支)

case  (不使用选择器)

case(使用选择器)

循环语句

LOOP循环

WHILE循环

FOR循环

游标的使用

隐式游标

显式游标

游标for循环

异常处理

预定义的异常

使用SQLCODE、SQLERRM函数进行异常处理

非预定义异常

用户定义的异常


 

 

概述:

PL/SQL是过程化的结构查询语言(Procedural Language/Structured Query Language),它可以弥补SQL语句的不足。

PL/SQL中可以通过IFLOOP语句控制程序的执行流程,并且可以定义变量,以便利用这些变量在语句之间传递数据信息。

PL/SQLOracle的专用语言,是对标准SQL语言的扩展SQL语句可以嵌套在PL/SQL程序代码中,将SQL的数据处理能力和PL/SQL的过程处理能力结合在一起。

 

什么是PL/SQL?

PL/SQL程序的基本结构称为块,编写PL/SQL程序实际就是编写PL/SQL块。
PL/SQL是一种块结构的语言,它将一组语句放在一个块中,一次性的发送给服务器,执行代码。
PL/SQL程序块分为无名块、命名块两种。
无名块指未命名的程序块,它没有被存储,每次执行后都不能被重用。
命名块指过程、函数、触发器和程序包等,可存储。
 

PL/SQL块的主要组成部分:

          声明部分、执行部分、异常处理部分

格式:

[DECLARE
DECLAREATION_STATEMENTS]
BEGIN
EXCUTABLE_STATEMENTS
[EXCEPTION
EXCEPTION _STATEMENTS]
END;

       说明:

声明部分DECLARE开始,是可选的
声明部分可以声明一些PL/SQL变量、常量、游标和异常等。当PL/SQL块结束后,声明部分的所有内容均不复存在。
在某个PL/SQL块中声明的内容只能在该块中使用,其他块不能使用。
执行部分BEGIN开始,是必须的
执行部分用于实现应用模块的功能,该部分包含了要执行的PL/SQL语句和SQL语句。
异常处理部分EXCEPTION开始,是可选的
异常处理部分用于处理执行部分可能出现的运行错误。
ENDPL/SQL块的结束标志。如果存在异常则以关键字EXCEPTION结束。
 

注意规范: 

PL/SQL块中的每一条语句都必须以分号结束SQL语句可以是多行的,但分号表示该语句结束。
一行中可以有多条SQL语句,但是他们之间必须以分号分隔。
 
注释方法:
单行注释:      --注释内容
多行注释:/*注释内容*/

标识符的命名规范

当定义变量时,建议用v_作为前缀。如v_sal
当定义常量时,建议用c_作为前缀。如c_rate
当定义游标时,建议用_cursor作为后缀。如emp_cursor;
当定义异常时,建议用e_作为前缀。如e_error
 

 变量与数据类型

        基本数据类型:BooleanBinary_intergerPls_intergerNumberIntCharVarchar2DateLong

        详细使用可自行查阅资料

      声明变量:

                             variable_name  data_type [ [NOT NULL]:=default_value_expression];  --有初始值

                              variable_name data_type [ [NOT NULL] DEFAULT default_value_expression];--无初始值

                              NOT NULL表示变量不允许为空

     变量定义举例:

SET SERVEROUTPUT ON  --显示结果
declare
v_name varchar2(8):=‘PJ’;       --变量声明
V_nowtime date:=sysdate;
begin
dbms_output.put_line(v_name);      --显示输出
dbms_output.put_line(v_nowtime);
end;
/                                --执行程序块

 

   

      注意:使用DBMS_OUTPUT包来显示查询结果或文本行时,需先执行SET SERVEROUTPUT ON语句。

标量变量

如果变量只能保存一个值,则该变量称为“标量变量”。如:charnumber……

%TYPE变量

在声明变量时,除了可以使用Oracle规定的数据类型外,还可以使用%TYPE关键字定义变量类型。
%TYPE关键字的含义是声明一个与指定列名称相同的数据类型
例如,下面的语句声明了一个与EMP表中ENAME列完全相同的数据类型:
var_name emp.ename%type;

      又如何从表中拿到数据放进变量中呢   格式:into 变量名

select ename into v_name
    from emp
    where empno=7369;

 

复合类型的变量

如果变量能保存多个值(如表中的一行记录,可参照为结构体变量。一张表,可参照为结构体数组),则该变量称为“复合类型的变量” 。如:%rowtype。可以通过.来调用成员变量
 
 %rowtype类型   :  变量名 表名%rowtype;    将一张表的结构给复合类型
 

定义格式 :v_name recode_name;

                   select *  into v_name  from 表名  --将表里面所有数据放入变量

 
 
 
 

            

 

          自定义记录类型  (类似于结构体定义)

 

          声明格式:  type record_name is record(

                               字段名1 类型;   

                               字段名2 类型;

                                 .....

                              );
例:emp表中工号为7369的职工的姓名(ename)、工种(job)、工资(sal)输出显示。

 

条件语句

if...then(单分支)

if <expression1> then  --expression1判断条件
pl/sql_statement;--符合if条件后要执行的pl/qsl语句
end if;                                   

if...then..else(双分支)

if <expression1> then
pl/sql_statement1;
else
pl/sql_statement2;
end if;                                  

if...then ...elsif(多分支)

if < expression1> then
       pl/sql_statement1;
elsif < expression2> then   ---注意这里是elsif,和我们平常的习惯可能不同
       pl/sql_statement2;
……
else
       pl/sql_statement3;
end if;                              

case  (不使用选择器)

case
when expression 1 then pl/sql_statement1;  --判断每个when子句的条件
when expression 2 then pl/sql_statement2;
....
when expression n then pl/sql_statementn;
[else expression n+1 then pl/sql_statement;]

end;

case(使用选择器)

case <selector>
when <expression1> then pl/sql_statement1;  --获取选择器的值,和每个when子句进行比较判断
when <expression 2> then pl/sql_statement2;
....
when <expression n> then pl/sql_statementn;
[else <expression n+1> then pl/sql_statement;]

end;

循环语句

PL/SQL中,常用的循环语句有3种类型,Loop,while,for

 

LOOP循环

LOOP循环也称为无条件的循环。在这种类型的循环中如果没有指定EXIT语句,循环将一直运行,即出现死循环。死循环是应该尽量避免的。因此,在LOOP循环中必须指定EXIT语句,以便循环停止执行。
loop
statements;--循环体
exit when condition;--跳出判断
end loop;

WHILE循环

while condition --适用于事先无法知道控制循环终止变量值的情况。
loop
statements;
end loop;

FOR循环

FOR循环则使用一个循环记数器,并通过它来控制循环执行的次数。该计数器可以从小到大进行记录,也可以相反,从大到小进行记录。如果不满足循环条件,则终止循环。
for loop_variable_name in [reverse] lower_bound..upper_bound
-- loop_variable_name 是指定循环计数器,可以使用已经有的,也可以使用一个新的。
-- 省略reverse,就是升序,不省略就是逆序。
-- for循环会自己,自增或自减1.不能在循环体里动态的去改变loop_variable_name的值
loop
statements;
end loop;

游标的使用

SQL 提供游标机制来实现在程序设计语言中处理集合

游标的作用就相当于指针,通过游标程序设计语言就可以一次处理查询结果集中的一行。

在Oracle中,游标可以分为两大类:静态游标和REF游标。

静态游标又可以分为显式游标和隐式游标。隐式游标和显示游标都是静态定义。在编译的时候结果集就已经被确定。
REF游标是一种引用类型,类似于指针。如果想在运行的时候动态确定结果集,就要使用REF游标.
 
 

隐式游标

在执行一个SQL语句时,Oracle会自动创建一个隐式游标。这个游标是内存中处理该语句的工作区域,在其中存储了执行SQL语句的结果。通过游标的属性可获知SQL语句的执行结果,以及游标的状态信息

游标的主要属性:

%FOUND       --若影响至少一条语句,返回true
%NOTFOUND   --与found相反
%ISOPEN          --游标是否打开(用于显式游标)
%ROWCOUNT   --返回受影响记录条数。
 

当使用隐式游标时,需要在前面加SQL(默认的游标名)

       

 

         cursor for loop语句:SQL语句返回的结果集进行处理

for 游标变量 in select语句
loop
DML操作
end loop;
 

显式游标

PL/SQL程序中处理结果集时,用户也可以通过显式定义游标,然后手动操作该游标处理结果集。
四个步骤:定义游标,打开游标,提取游标数据,关闭游标
 
--定义游标:
  Cursor 游标名 is select语句;  --不带参数的游标
  Cursor 游标名(参数名1 类型名1,参数名2 类型名2,……) is select语句; --带参数的游标
--打开游标
  open 游标名;
  open 游标名(实参值1,实参值2,……)
--提取游标数据
   fetch 游标名 into 记录变量名;
--关闭游标。
   close 游标名;

举例:

游标for循环

 

游标通常是与循环联合使用。实际上,PL/SQL还提供了一种将两者综合在一起的语句,即游标FOR循环语句。游标FOR循环是显式游标的一种快捷使用方式,它使用FOR循环依次读取结果集中的数据。FOR循环开始时,游标会自动打开(不需要使用OPEN方法),每循环一次系统自动读取游标当前行的数据(不需要使用FETCH),当退出FOR循环时,游标被自动关闭(不需要使用CLOSE

 

 
--在SCOTT模式下显示工资排名前5的员工的编号、姓名和工资。

declare
cursor emp_cur is select empno,ename,sal from
		(select empno,ename,sal from emp order by sal desc) where rownum<6;
begin
for i in emp_cur loop
dbms_output.put_line(i.empno|| ' ' || i.ename|| ' '|| i.sal);
end loop;
end;
/

 

 

异常处理

在编写PL/SQL程序时,不可避免地会出现一些错误。在Oracle系统中使用异常来处理这些错误,这些异常都可以包括在PL/SQL程序的EXCEPTION块中。Oracle系统提供了许多内置的异常,用户也可以根据自己的需要定义异常

Oracle系统中的异常可以分为3

预定义的异常:Oracle提供,用户无需在程序中定义,由Oracle自动引发。

非预定义异常:数据库本身不知道、不能控制的错误。需要用户在程序中定义,然后由Oracle自动引发。

用户定义的异常:违反了业务逻辑,程序员可以明确定义并引发。

 

预定义的异常

举例:

使用SQLCODESQLERRM函数进行异常处理

非预定义异常

在一个异常产生、被捕获并处理之前,它必须被定义。Oracle定义了几千个异常,绝大多数只有错误编号和相关描述,仅仅命名了21个最常被用到的异常,即系统预定义异常。这些异常的名称被储存在STANDARDUTL_FILEDBMS_SQL这几个系统包中。

使用pragma exception_init语句可以为错误关联一个名字

--已知Oracle中一错误代码ORA-01400: 无法将 NULL 插入,
--请将该错误代码与NULL_INSERT_ERROR进行关联,并利用Scott模式下的表(
--例如,emp或dept)操作,举例报出该错误。
declare
null_insert_error exception;
pragma exception_init(null_insert_error,-1400);

begin

insert into emp(empno) values(NULL);

exception
when null_insert_error then
dbms_output.put_line('无法将NULL插入');
end; 

用户定义的异常

程序开发人员可以根据具体的业务逻辑规则,自定义一个异常。这样,当用户操作违反了业备逻辑规则后,就引发一个自定义异常,从而中断程序的正常执行,并转到自定义的异常处理部分。

--定义异常处理
declare
异常名 exception;

--触发异常处理
raise 异常名;

--处理异常,在exception,中处理
--自定义一个异常,在SCOTT模式下,如果查找到EMP表中的某一员工
--(员工编号由用户任意输入)的佣金(COMM字段)为0时,则显示自定义错误消息“该员工的佣金为0”。


declare
v_sal emp.sal%type;
e_sal exception;
v_eno emp.empno%type:=&no;
		
begin
select sal into v_sal from emp where empno=v_eno;
if emp_cur.sal=0 then --触发异常的逻辑判断
raise e_sal;

exception 
when e_sal then 
dbms_output.put_line('该员工的佣金为0!');

end;
/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章