Oracle+11g+笔记(2)-Oracle PL/SQL语言及编程
2、Oracle PL/SQL语言及编程
PL/SQL(Procedual Language/SQL)
是Oracle
在标准SQL语言上进行过程性扩展后形成的程序设计语言,是一
种 Oracle 数据库特有的、支持应用开发的语言。
2.1 PL/SQL的基本结构
和所有过程化语言一样,PL/SQL
也是一种模块式结构的语言,其大体结构如下:
DECLARE
-- 声明一些变量、常量、用户定义的数据类型以及游标等
-- 这一部分可选,如不需要可以不写
BEGIN
--主程序体,在这里可以加入各种合法语句
EXCEPTION
-- 异常处理程序,当程序中出现错误时执行这一部分
END;
-- 主程序体结束
从上面这个结构可以看出,它包含3
个基本部分:声明部分(declarative section
)、执行部分(executable
section
)和异常处理部分(exception section
)。其中,只有执行部分是必须的,其他两个部分都是可选的。需
要强调的是,该结构最后的分号是必需的。
如果没有声明部分,结构就以BEGIN
关键字开头,如果没有异常处理部分,关键字EXCEPTION
将被省略,END
关
键字后面紧跟着一个分号结束该块的定义,这样,仅包含执行部分的结构定义如下所示:
BEGIN
/*执行部分*/
END;
如果一个块带有声明和执行部分,但是没有异常处理部分,其定义如下:
DECLARE
/*声明部分*/
BEGIN
/*执行部分*/
END;
2.2 PL/SQL注释
2.2.1 单行注释
单行注释:--
。
DECLARE
V_Department CHAR(3); -- 保存3个字符的变量
-- 系代码
V_Course NUMBER; -- 保存课程号的代码
BEGIN
-- 插入一条记录
INSERT INTO classes(department,course) VALUES(V_Department,V_Course);
END;
提示:如果注释超过一行,就必须在每一行的开头使用双连字符(--
)。
2.2.2 多行注释
多行注释由/*
开头,由*/
结尾,这和C语言是一样的。
DECLARE
V_Department CHAR(3); /* 保存3个字符的变量,系代码 */
V_Course NUMBER; /* 保存课程号的代码 */
BEGIN
/* 插入一条记录 */
INSERT INTO classes(department,course) VALUES(V_Department,V_Course);
END;
2.3 PL/SQL字符集
2.3.1 合法字符集
所有的PL/SQL
程序都是由一些字符序列编写而成的,这些字符序列中的字符取自PL/SQL
语言所允许使用的字符
集。该字符集包括:
-
大写和小写字母,
A~Z
和a~z
。 -
数字
0~9
。 -
非显示的字符、制表符、空格和回车。
-
数学符号
+
,-
,*
,/
,<
,>
,=
。 -
间隔符,包括
()
,{}
,[]
,?
,!
,;
,:
,’
,”
,@
,#
,%
,$
,^
,&
等。
除了引号引起来的字符,PL/SQL
不区分字符的大小写。
2.3.2 分界符
分界符(delimiter
)是对 PL/SQL 有特殊意义的符号(单字符或者字符序列)。它们用来将标识符相互分割开。下表
列出了在PL/SQL 中可以使用的分界符。
2.4 PL/SQL数据类型
2.4.1 数字类型
数字类型变量存储整数或者实数。它包含NUMBER
、PLS_INTEGER
和BINARY_INTEGER
3种基本类型。其
中,NUMBER
类型的变量可以存储整数或浮点数,而BINARY_INTEGER
或PLS_INTEGER
类型的变量只存储整数。
NUMBER(P,S)
是一种格式化的数字,其中P
是精度,S
是刻度范围。精度是数值中所有有效数字的个数,而刻度
范围是小数点右边数字位的个数。精度和刻度范围都是可选的,但如果指定了刻度范围,那么也必须指定精度。
提示:如果刻度范围是个负数,那么就由小数点开始向左边计算数字位的个数。
“子类型”(subtype
)是类型的一个候选名,它是可选的,可以使用它来限制子类型变量的合法取值。有多种与
NUMBER
等价的子类型,实际上,它们是重命名的NUMBER
数据类型。有时候可能出于可读性的考虑或者为了与来
自其他数据库的数据类型相兼容会使用候选名。这些等价的类型包括DEC
、DECIMAL
、DOUBLE
、PRECISION
、
INTEGER
,INT
、NUMERIC
、REAL
、SMALLINT
、BINARY_INTEGER
、PLS_INTEGER
。
2.4.2 字符类型
字符类型变量用来存储字符串或者字符数据。其类型包括VARCHAR2
、CHAR
、LONG
、NCHAR
和NVARCHAR2
(后两
种类型在PL/SQL8.0
以后才可以使用)。
VARCHAR2
类型和数据库类型中的VARCHAR2
类似,可以存储变长字符串,声明语法为:
VARCHAR2(MaxLength);
MaxLength
的最大长度是32767字节,数据库类型的VARCHAR2
的最大长度是4000字节。
VARCHAR2
没有默认的长度。
CHAR
类型表示定长字符串。声明语法为:
CHAR(MaxLength);
MaxLength
的最大长度为32767字节,默认长度为1。
如果赋给CHAR
类型的值不足MaxLength
,则在其后面用空格补全,这也是不同于VARCHAR2
的地方。
数据库类型的CHAR
的最大长度是2000字节。
LONG
类型变量是一可变的字符串,最大长度是 32760 字节。LONG 变量与VARCHAR2 变量类似。数据库类型的
LONG长度最大可达2GB,所以几乎任何字符串变量都可以赋值给它。
提示:NCHAR
和NVARCHAR2
类型是PL/SQL8.0
以后才加入的类型,它们的长度指定根据各国字符集的不同而不
同。
2.4.3 日期类型
日期类型中只有一种类型DATE
,用来存储日期和时间信息,包括世纪、年、月、天、小时、分钟和秒。DATE变量
的存储空间是7个字节,每个部分占用一个字节。
2.4.4 布尔类型
布尔类型中的唯一类型是BOOLEAN
,主要用于控制程序流程。一个布尔类型变量的值可以是TRUE
、FALSE
或
NULL
。
2.4.5 type定义的数据类型
它类似C语言中的结构类型,定义数据类型的语句格式如下:
type<数据类型名> is <数据类型>;
在Oracle 中允许用户定义两种数据类型,它们是RECORD
(记录类型)和TABLE
(表类型)。
【使用type
定义teacher_record
记录变量】。
type teacher_record is RECORD
(
TID NUMBER(5) NOT NULL:=0,
NAME VARCHAR2(50),
TITLE VARCHAR2(50),
SEX CHAR(1)
);
该RECORD定义后,在以后的使用中就可以定义基于teacher_record
的记录变量。
【定义一个 teacher_record
类型的记录变量 ateacher
】。
teacher teacher_record;
引用这个记录变量时要指明内部变量,如ateacher.tid
或ateacher.name
。
另外,PL/SQL
还提供了%TYPE
和%ROWTYPE
两种特殊的变量,用于声明与表的列相匹配的变量和用户定义数据
类型,前一个表示单属性的数据类型,后一个表示整个属性列表的结构,即元组的类型。
【将上述例中的 teacher_record
定义成】
type teacher_record is RECORD
(
TID TEACHERS.TID%TYPE NOT NULL:=0,
NAME TEACHERS.NAME%TYPE,
TITLE TEACHERS.TITLE%TYPE,
SEX TEACHERS.SEX%TYPE
);
也可以定义一个与表TEACHERS
的结构类型一致的记录变量,如下所示:
teacher_record TEACHERS%ROWTYPE;
2.5 常量和变量
2.5.1 定义常量
<常量名> constant <数据类型>:=<值>;
Pass_Score constant INTERGE:=60;
常量一旦定义将不可改变。
2.5.2 定义变量
<变量名><数据类型>[(宽度):=<初始值>];
address VARCHAR2(30);
2.5.3 变量初始化
一般而言,如果变量的取值可以被确定,那么最好为其初始化一个数值。
但是,PL/SQL
定义了一个未初始化变量应该存放的内容,被赋值为 NULL。 NULL意味着"未定义或未知的取值"。
换句话讲,NULL可以被默认地赋值给任何未经过初始化的变量。
2.6 语句控制结构
选择结构
2.6.1 IF语句
IF(条件表达式1) THEN
{语句序列1;}
[ELSIF(条件表达式2) THEN
{语句序列2;)]
[ELSE
{语句序列 3;)]
END IF;
# 第一种情况:IF...THEN语句
IF NO=98020 THEN -- 此处NO值通过游标得到,有关游标后面将讲到
INSERT INTO temp_table values(NAME,BIRTHDAY);
END IF;
# 第二种情况:IF...THEN...ELSE语句
IF NO=98020 THEN -- 如果NO值为98020则执行下面语句
INSERT INTO found_table values(NAME,BIRTHDAY);
ELSE -- 否则执行下面语句
INSERT INTO notfound_table values(NAME,BIRTHDAY);
END IF;
# 第三种情况:IF...THEN...ELSEIF语句
IF score>90 THEN -- 如果score大于90则执行下面语句
Score:=score-5;
ELSIF score<60 THEN -- 否则,如果 score小于60则执行下面语句
Score:=score+5;
END IF;
2.6.2 CASE语句
Oracle 9i
之后新增的结构。
CASE 检测表达式
WHEN 表达式1 THEN 语句序列1
WHEN 表达式2 THEN 语句序列2
...
WHEN 表达式n THEN 语句序列n
[ELSE 其他语句序列]
END;
ELSE
语句是可选的,如果检测表达式的值与下面任何一个表达式的值都不匹配时,PL/SQL会产生预定义错误
CASE NOT FOUND
。注意:CASE语句中表达式1到表达式n的类型必须同检测表达式的类型相符。一旦选定的语句
序列被执行,控制就会立即转到CASE语句之后的语句。
DECLARE
V_grade VARCHAR2(20):='及格';
v_score VARCHAR2(50);
BEGIN
v_score:=CASE v_grade
WHEN '不及格' THEN '成绩<60'
WHEN '及格' THEN '60<=成绩<70'
WHEN '中等' THEN '70<=成绩<80'
WHEN '良好' THEN '80<=成绩<90'
WHEN '优秀' THEN '90<=成绩<=100'
ELSE '输入有误'
END;
dbms_output.put_line(v_score);
END;
# 执行结果
60<=成绩<70
NULL结构
在IF 结构中,只有相关的条件为真时,相应的语句才执行,如果条件为FALSE 或者NULL时,语句都不会执行。特
别是当条件为NULL时,常常会对程序的流程和输出有比较大的影响。请对比以下两个例子。
DECLARE
V_NUMBER1 NUMBER;
V_NUMBER2 NUMBER;
V_Result VARCHAR2(7);
BEGIN
IF V_NUMBER1 < V_NUMBER2 THEN
V_Result:='Yes';
ELSE
V_Result:='No';
END IF;
-- No
dbms_output.put_line(V_Result);
END;
DECLARE
V_NUMBER1 NUMBER;
V_NUMBER2 NUMBER;
V_Result VARCHAR2(7);
BEGIN
IF V_NUMBER1 > V_NUMBER2 THEN
V_Result:='No';
ELSE
V_Result:='Yes';
END IF;
-- Yes
dbms_output.put_line(V_Result);
END;
DECLARE
V_NUMBER1 NUMBER