大型数据库技术(六)PL/SQL语言

一、PL/SQL语言简介

1.特点:

基于事务处理的语言,支持所有数据处理命令。
PL/SQL与Oracle数据字典结合。
PL/SQL块可以被命名存储,具有很好的可重用性。
具有很好的安全性。
PL/SQL代码可以使用任何ASCII文本编辑器编写。
减少对Oracle服务器内核的访问,降低网络负荷。

2.结构

一个PL/SQL程序包含了一个或多个逻辑块,每个块都 可以划分为三个部分。
DECLARE
--- 变量声明
BEGIN
--- 语句序列
EXCEPTION
--- 异常处理
END;

二、变量声明与赋值

1.说明

声明部分包含了变量和常量的数据类型和初始值以及 游标 的声明。
异常处理部分是可选的。
PL/SQL块中的每一条语句都必须以 分号 结束。
单行注释由“--”标示, 多行注释由“/* */”标示
变量在使用之前必须声明。
变量不区分大小写。
声明变量的语法:
variable_name [CONSTANT] datatype [NOT NULL][:=|DEFAULT expression] ;
例如:
v_StudentID NUMBER(5):=10000;
v_NumberSeats NUMBER DEFAULT 45;

2.使用%type声明变量

使用%TYPE属性声明变量的类型,这个属性被附加在 表列引用或者另一个变量上,并返回其类型。
更加适应数据库定义的变更。
  例如:
v_FirstName students.first_name%TYPE;

3.变量赋值

  直接对变量赋值,例如:
v_1:=200;
  通过SQL SELECT INTO 或FETCH INTO(使用游标的情
况下)给变量赋值。例如:
SELECT number_seats INTO v_NumberSeats
FROM rooms WHERE room_id = 99999;

三、变量数据类型

数据类型决定了变量、常量和列数据的存储格式和取 值范围等属性。
PL/SQL的数据类型:

1.标量数据类型

数字(number)
字符(character)
日期(date)
布尔(boolean)
行标识(rowid):查询rowid
SELECT rowid FROM rooms

2.大型对象数据类型

大型对象(LOB)数据类型用于存储类似图像、声音 这样的大型数据对象。
LOB数据对象可以是二进制数据也可以是字符数据, 其最大长度不超过4G。
LOB数据类型可分为以下四类:BFILE、BLOB、CLOB和 NCLOB。
BFILE类型
也称为“外部LOB”。
FILE数据存储在单独的文件中。
表中仅存储一个“LOB定位符”(LOB locator) ,该定
位符是一个指向实际数据的指针。
使用BFILE数据的步骤包括:
创建存储外部文件的目录。
用户获得相应的存取该目录的权限。
用户通过该目录存取外部文件。
CONNECT system/manager
--以system身份登录
CREATE OR REPLACE DIRECTORY photo as 'c:\oracle\photo';
--创建目录存储图像文件,并命名为photo
GRANT READ ON DIRECTORY photo to Trainee;
--授权给用户Trainee访问该目录的权限
CONNECT Trainee/t123456
--以Trainee身份登录
CREATE TABLE personal(name varchar2(20),photo bfile);
--创建表personal,其中的photo字段为BFILE类型
INSERT INTO personal VALUES('Jack 
Berry',bfilename('photo','1.bmp'));
--向表中插入一条记录,该记录的photo值为文件1.bmp,保存在c:\oracle\photo目录下。

3.复合数据类型

记录类型

相当于数据库表中的数据行
记录中的不同字段相当于一个数据行中的不同列
不同字段具有不同的数据类型
TYPE <recordtypename> IS RECORD
( <fieldname> <datatype> [[NOT NULL] 
{DEFAULT|:=} <expression>]
[,<fieldname> …] );


DECLARE
TYPE t_StudentRecord IS RECORD(
StudentID NUMBER(5),
FirstName VARCHAR2(20),
LastName VARCHAR2(20));
v_StudentInfo t_StudentRecord;
BEGIN
v_StudentInfo.StudentID:=1;
v_StudentInfo.FirstName:=’John’;
v_StudentInfo.LastName:=’Smith’; 
END;
使用%ROWTYPE属性
%ROWTYPE返回一个基于表定义的类型。
使用%ROWTYPE属性,可以将一个记录声明为具有相同 类型的数据库行。
DECLARE
v_StudentInfo1 students%ROWTYPE; 
SELECT * INTO v_StudentInfo1 
FROM students 
WHERE ID = 10000;

② 表类型

又可称为集合类型
所有元素具有相同的数据类型
相当于数据库表中的列
TYPE tabletype IS TABLE OF type INDEX BY BINARY_INTEGER;
DECLARE 
TYPE t_NameTable IS TABLE OF students.first_name%TYPE
INDEX BY BINARY_INTEGER;
TYPE t_DateTable IS TABLE OF DATE
INDEX BY BINARY_INTEGER;
v_Names t_NameTable;
v_Dates t_DateTable;
BEGIN
v_Names(1):=’Scott’;
v_Dates(-4):=SYSDATE -1;
END;
使用表类型的注意事项
在表中能够存储的元素个数只受到BINARY_INTEGER类 型的取值范围的限制。
表中的元素可以按照任意的键值(KEY)进行插入。
键值也没有必要是顺序的。
对表中元素i赋值实际上创建了这个元素。
数据被插入时,表所需要的内存才被分配。
表中的元素可以是一条记录 ,例如:
SET SERVEROUTPUT ON
DECLARE
TYPE t_StudentTable IS TABLE OF students%ROWTYPE
INDEX BY BINARY_INTEGER;
/* v_Students的每个元素值是一条记录 */
v_Students t_StudentTable;
BEGIN
/* 从students表中检索 id = 10001 的记录并存储在v_Students(10001)中 */
SELECT *
INTO v_Students(10001)
FROM students
WHERE id = 10001;
v_Students(10001).first_name := 'Larry';
DBMS_OUTPUT.PUT_LINE(v_Students(10001).first_name);
END;

四、表属性

COUNT属性
返回表中的行数
DELETE属性
从表中删除元素
EXISTS属性
如果带有索引i的元素在表中,那么表名.EXISTS(i)返回TRUE,否则它返回FALSE。
DECLARE
TYPE t_FirstNameTable IS TABLE OF students.first_name%TYPE
INDEX BY BINARY_INTEGER;
FirstNames t_FirstNameTable;
BEGIN
FirstNames(1) := 'Scott';
IF FirstNames.EXISTS(1) THEN
DBMS_OUTPUT.PUT_LINE('Row 1 exists!');
END IF;
END;
FIRST和LAST属性
分别返回表中第一个元素和最后一个元素的索引
第一个元素被定义为拥有最小索引值的元素
最后一个元素是拥有最大索引值的元素
DECLARE
TYPE t_LastNameTable IS TABLE OF students.last_name%TYPE
INDEX BY BINARY_INTEGER;
v_LastNames t_LastNameTable;
v_Index_first BINARY_INTEGER;
v_Index_last BINARY_INTEGER;
BEGIN
v_LastNames(43) := 'Mason';
v_LastNames(50) := 'Junebug';
v_LastNames(47) := 'Taller';
v_Index_first:= v_LastNames.FIRST;
v_Index_last:= v_LastNames.LAST;
DBMS_OUTPUT.PUT_LINE( v_Index_last);
END;
NEXT和PRIOR属性
分别返回表中下一个元素的索引或者上一个元素的索引
可以在对整个表进行迭代处理的循环中使用
DECLARE
TYPE t_MajorTable IS TABLE OF students.major%TYPE
INDEX BY BINARY_INTEGER;
v_Majors t_MajorTable;
v_Index BINARY_INTEGER;
BEGIN
v_Majors(-7) := 'Computer Science';
v_Majors(4) := 'History';
v_Majors(5) := 'Economics';
v_Index := v_Majors.FIRST;
LOOP
INSERT INTO temp_table (num_col, char_col) 
VALUES (v_Index, v_Majors(v_Index));
EXIT WHEN v_Index = v_Majors.LAST;
v_Index := v_Majors.NEXT(v_Index);
END LOOP;
END; 

五、PL/SQL控制结构

1.条件语句

IF condition1 THEN
 statement1;
[ELSIF condition2 THEN
 statement2;]
…
[ELSE
 statement3;]
END IF;
例子:
DECLARE
v_NumberSeats rooms.number_seats%TYPE;
v_Comment VARCHAR2(35);
BEGIN
SELECT number_seats INTO v_NumberSeats 
FROM rooms WHERE room_id = 99999;
IF v_NumberSeats < 50 THEN
v_Comment := 'Fairly small';
ELSIF v_NumberSeats < 100 THEN
v_Comment := 'A little bigger';
ELSE
v_Comment := 'Quite big';
END IF;
DBMS_OUTPUT.PUT_LINE(v_Comment);
END;

2.循环语句

直到型循环loop

LOOP
statements1;
EXIT [WHEN condition];
[statements2;]
END LOOP;

WHILE循环

WHILE condition LOOP
statements;
END LOOP;DECLARE
v_Counter BINARY_INTEGER := 1;
BEGIN
WHILE v_Counter <= 50 LOOP
INSERT INTO temp_table
VALUES (v_Counter, 'Loop index');
v_Counter := v_Counter + 1;
END LOOP;
END;

FOR循环

FOR counter IN [REVERSE] low_bound..high_bound LOOP
statements;
END LOOP;

BEGIN
FOR v_Counter IN 1..50 LOOP
INSERT INTO temp_table
VALUES (v_Counter, 'Loop Index');
END LOOP;
END;

3. GOTO与标签

语法为:
 
GOTO label;
DECLARE
v_Counter BINARY_INTEGER := 1;
BEGIN
LOOP
INSERT INTO temp_table VALUES (v_Counter, 'Loop count');
v_Counter := v_Counter + 1;
IF v_Counter > 50 THEN
GOTO l_EndOfLoop;
END IF;
END LOOP;
<<l_EndOfLoop>>
INSERT INTO temp_table (char_col)
VALUES ('Done!');
END; 

小结:

课堂小结
在这一课里,我们学到了:
PL/SQL是对SQL 语言的过程化扩展。
PL/SQL将SQL的数据操纵功能与过程化语言数据处理 功能结合起来,并能与数据库核心的数据类型集成, 具有很高的执行效率。
使用PL/SQL可以减少对Oracle服务器内核的访问,降 低网络负荷。
PL/SQL是一种块结构语言。
可以使用%TYPE属性声明变量的类型,这个属性被附 加在表列引用或者另一个变量上,并返回其类型。
大型对象(LOB)数据类型用于存储类似图像、声音 这样的大型数据对象。
PL/SQL记录类型类似于C语言中的结构,记录的每个 字段可以具有不同的数据类型。
在定义记录类型时,一种常见的做法是使用%ROWTYPE 属性,将一个记录声明为具有相同类型的数据库行。
PL/SQL的表类型类似于数组。
PL/SQL的控制结构包括条件语句和循环。
循环语句分为直到型循环、WHILE循环和FOR循环。
当执行GOTO语句时,控制会立即转到由标签标识的语 句。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值