08、Oracle 入门教程 - Oracle SQL语言之PL/SQL 编程

PL/SQL(Procedural Language/SQL)是Oracle在数据库中引入的一种过程化编程语言。PL/SQL构建于SQL之上,可以用来编写包含SQL语句的程序。

一、PL/SQL 概述

1.1 PL/SQL 简介

1.1.1 PL/SQL 简介
PL/SQL(Procedural Language/SQL)是一种过程化语言,在PL/SQL中可以通过IF语句或LOOP语句实现控制程序的执行流程,甚至可以定义变量,以便在语句之间传递数据信息,这样PL/SQL语言就能够实现操控程序处理的细节过程,不像普通的SQL语句(如DML语句、DQL语句)那样没有流程控制,也不存在变量,因此使用PL/SQL语言可以实现比较复杂的业务逻辑。

PL/SQL是Oracle的专用语言,它是对标准SQL语言的扩展,它允许在其内部嵌套普通的SQL语句,这样就将SQL语句的数据操纵能力、数据查询能力和PL/SQL的过程处理能力结合在一起,达到取长补短的目的。

1.1.2 PL/SQL块结构
PL/SQL程序都是以块(BLOCK)为基本单位,整个PL/SQL块分三部分:声明部分(用DECLARE开头)、执行部分(以BEGIN开头)和异常处理部分(以EXCEPTION开头)。其中执行部分是必须的,其他两个部分可选。无论PL/SQL程序段的代码量有多大,其基本结构都是由这三部分组成。

标准PL/SQL块的语法格式如下:

[DECLARE]
        --声明部分,可选
BEGIN
        --执行部分,必须
[EXCEPTION]
        --异常处理部分,可选
END

(1)声明部分

  • 声明部分由关键字DECLARE开始,到BEGIN关键字结束。在这部分可以声明PL/SQL程序块中所用到的变量、常量和游标等。
  • 需要注意的是:在某个PL/SQL块中声明的内容只能在当前块中使用,而在其他PL/SQL块中是无法引用的。

(2)执行部分

  • 执行部分以关键字BEGIN开始,它的结束方式通常有两种。
  • 如果PL/SQL块中的代码在运行时出现异常,则执行完异常处理部分的代码就结束;
  • 如果没有使用异常处理或PL/SQL块未出现异常,则以关键字END结束。
  • 执行部分是整个PL/SQL程序块的主体,主要的逻辑控制和运算都在这部分完成,所以在执行部分可以包含多个PL/SQL语句和SQL语句。

(3)异常处理部分

  • 异常处理部分以关键字EXCEPTION开始,在该关键字所包含的代码执行完毕后,整个PL/SQL块也就结束了。
  • 在执行PL/SQL代码(主要是执行部分)的过程中,可能会产生一些意想不到的错误,比如除数为零,空值参与运算等,这些错误都会导致程序中断运行。这样程序设计人员就可以在异常处理部分通过编写一定量的代码来纠正错误或者给用户提供一些错误信息提示,甚至是将各种数据操作回退到异常产生之前的状态,以备重新运行代码块。
  • 另外,对于可能出现的多种异常情况,用户可以使用WHEN THEN语句来实现多分支判断,然后在每个分支下通过编写代码来处理相应的异常。

对于PL/SQL块中的语句,需要指出的是:每一条语句都必须以分号结束,每条SQL语句可以写成多行的形式,同样必须使用分号来结束。另外,一行中也可以有多条SQL语句,但是它们之间必须以分号分隔。

1、 1.3示例;

SQL> set serveroutput on
SQL> declare
  2  		a int := 100;
  3  		b int := 100;
  4  		c number;
  5  begin
  6  		c := (a + b) / (a - b);
  7  		dbms_output.put_line(c);
  8  exception
  9  		when zero_divide then
 10  		dbms_output.put_line('除数不能为零');
 11  end;
 12  /

 

  • 在上面的代码中,首先使用set serveroutput on命令来实现在服务端显示执行结果;
  • 然后使用declare关键字声明3个变量,其中,前两个整型(int)变量a和b的初始值分别为100和200;
  • 最后在PL/SQL块的执行部分计算出这两个整数的和与它们之间差的商,并调用dbms_output.put_line(c);语句输出计算结果。

另外,为了防止除数为零的情况发生,代码中还设置了异常处理部分。若发生除数为零的情况,则代码块通过调用dbms_output.put_line('除数不许为零!');语句向用户输出提示信息。

1.2 注释、标示符

1.2.1 介绍
注释用于对程序代码进行解释说明,它能够增强程序的可读性,使程序更易于理解。注释编译时会被PL/SQL编译器忽略掉,注释有单行注释和多行注释两种情况。

另外,在PL/SQL块中声明的变量、常量、游标和存储过程等标识符的名称都是由一系列字符集所组成的,Oracle对这些组成标识符的字符集有一定的规范和要求。

1.2.2 单行注释
单行注释由两个连接字符“–”开始,后面紧跟着注释内容。

SQL> set serveroutpu on                                        --在服务器端输出结果
SQL> declare
  2  	Num_sal number;                                         --声明一个数值变量
  3  	Var_ename varchar2(20);                                 --声明一个字符串变量
  4  begin
  5  	select ename,sal into Var_ename,Num_sal from scott.emp        --检索指定的值并存储到变量中
  6  	where empno=7369;
  7  	dbms_output.put_line(Var_ename||'的工资是'||Num_sal);   --输出变量中值
  8  end;
  9  /
SMITH的工资是800

PL/SQL procedure successfully completed

 

如果注释超过一行,就必须在每一行的开头使用连接字符(–)。

1.2.3 多行注释

多行注释由/*开头,以*/结尾,这种多行注释的方法在大多数的编程语言中是相同的。

SQL> set serveroutpu on                    /*在服务器端输出结果*/
SQL> declare
  2  	Num_sal number;                    /*声明一个数值变量*/
  3     Var_ename varchar2(20);            /*声明一个字符串变量*/
  4  begin
  5      /*检索指定的值并存储到变量中*/
  6      select ename,sal into Var_ename,Num_sal from scott.emp
  7      where empno=7369;
  8      /*输出变量中值*/
  9      dbms_output.put_line(Var_ename||'的工资是'||Num_sal);
 10  end;
 11  /
SMITH的工资是800

PL/SQL procedure successfully completed

 

1.2.3 标识符

标识符(identifier)用于定义PL/SQL块单元和程序项的名称。通过使用标识符,可以定义常量、变量、异常、显式游标、游标变量、参数、子程序及包的名称。

当使用标识符定义PL/SQL块或程序单元时,需要满足以下规则:

  • 当定义变量、常量时,每行只能定义一个变量或者常量(行终止符:;)。
  • 当定义变量、常量时,名称必须以英文字符(A~Z、a~z)开始,并且最大长度为30个字符。如果以其他字符开始,那么必须使用双引号引住。
  • 当定义变量、常量时,名称只能使用符号A~Z、a~z、0~9、_、$和#。如果使用其他字符,那么必须用双引号引住。
  • 当定义变量、常量时,名称不能使用Oracle关键字。例如不能使用SELECT、UPDATE等作为变量名。如果要使用Oracle关键字定义变量、常量,那么必须使用双引号引住。

(1)合法的标识符

所有的PL/SQL程序元素(比如关键字、变量名、常量名等)都是由一些字符序列组合而成的,而这些字符序列中的字符都必须取自PL/SQL语言所允许使用的字符集,那么这些合法的字符集主要包括以下内容:

  • 大写和小写字母:A~Z或a~z。
  • 数字:0~9。
  • 非显示的字符:制表符、空格和回车。
  • 数学符号:+,-,*,/,><,=等。
  • 间隔符:包括(),{},[],?,!,;,:,@,#,%,$,&等。

只有上面列出的这些符合要求的字符才可以在PL/SQL程序标识符中使用,其他的字符都是非法的,不可以使用。类似于SQL,除了由引号引起来的字符串以外,PL/SQL不区分字母的大小写。标准PL/SQL字符集是ASCII字符集的一部分。ASCII是一个单字节字符集,这就是说每个字符可以表示为一个字节的数据,该性质将字符总数限制在最多为256个。

示例

v_ename           VARCHAR2(10);
v$sal             NUMBER(6,2);            v#sal      NUMBER(6,2);
v#error           EXCEPTION;
“1234”          VARCHAR2(20);           --以数字开始,带有双引号
“变量 A”        NUMBER(10,2);           --包含数字,带有双引号

(2)非法的标识符
示例

v%ename    VARCHAR2(10);              --非法符号(%)
2sal       NUMBER(6,2);               --以数字开始非法
#vl        EXCEPTION;                 --以#开始非法
v1,v2      VARCHAR2(20);              --每行只能定义一个变量
变量 A      NUMBER(10,2);              --不能以汉字开始
select     NUMBER(10,2)            	  --不能使用关键字作为变量名

注意Oracle不支持其他的多字节字符集,这些多字节字符集的字符数目会超过256个。对于不使用英语字母表的语言,多字节字符集是必需的。

1.3 分界符

分界符(delimiter)是对PL/SQL有特殊意义的符号(单字符或者字符序列)。它们用来将标识符相互分割开。下图列出了在PL/SQL中可以使用的分界符。

 

1.4 文本

1.4.1 文本介绍

文本是指实际的数值的文字,包括数字文本、字符文本、字符串文本、布尔文本、日期时间文本等。

1.4.2 数字文本

数字文本是指整数或者浮点数。当编写PL/SQL代码时,可以使用科学计数法和幂操作符(**)。

科学计数法和幂操作符只适用于PL/SQL语句,而不适用于SQL语句。

数字文本如下所示:

100   2.45   3e3   5E6   6*10**3 

1.4.3 字符文本
字符文本是指用单引号引住的单个字符,这些字符可以是PL/SQL支持的所有可打印字符,包括英文字符(A~Z、a~z)、数字字符(0~9)及其他字符(<、>等)。

字符文本如下所示:

'A'   '9'   '<'   ' '   '%'  

1.4.4 布尔文本

布尔文本是指BOLLEAN值(TRUE、FALSE和NULL),并且布尔文本主要用在条件表达式中。

1.4.5 日期时间文本

日期时间文本是指日期时间值,日期文本必须用单引号引住,并且日期值必须与日期格式和日期语言匹配。

日期文本如下所示:

'10-NOV-91'   '1997-10-22 13:01:01'   '09-10-月-03' 

1.4.6 字符串文本

字符串文本是指由两个或两个以上字符组成的多个字符值,字符串文本必须用单引号引住。

字符串文本如下所示:

'Hello World'   '$9600'   '10-NOV-91' 

在Oracle Database 10g之前,如果字符串文本包含单引号,那么必须使用两个单引号表示。例如,如果要为某个变量赋值I’m a string, you’re a string,那么字符串文本必须要采用以下格式

string_var:= 'I''m a string,you''re a string';

在Oracle Database 10g之后,如果字符串文本包含单引号,那么既可以使用原有格式进行赋值,也可以使用其他分隔符([]、{}、<>等)进行赋值。

如果要使用分隔符[]、{}、<>为字符串赋值,那么不仅需要在分隔符前后加单引号,而且需要带有前缀q。

示例:

string_var:= q'[I'm a string,you're a string.]';