第一章 PL/SQL 介绍

68
PL/SQL 第第 1.1 什什什 PL/SQL 第第第第第第第 (Structured Query Lan guage 第第 SQL) 第第第第第第第第第第第 第第第第第第 第第第第第第第第第 一,( 4 GL 第第第第第第第第第第第 第第第第第第第第第第 第第第第第第 第第第第第第第 ),,体, 第第第第第第第第第第第第第delete from students where ma jor=‘Nutrition’; 第第 第第第第第第第第第第第第第第第第第第第第第第第 第第 ,, 4GL 第第第第第第第第PL/SQL 第第第第第第第第第第第第第第第第第第第第 SQL 第第第第第 第第第第第第第第 第第第第第第第第第 第第第第第 第第第第第第 ,一,一。

description

第一章 PL/SQL 介绍. 1.1  什么是 PL/SQL 结构化查询语言 (Structured Query Language ,简称 SQL) 是用来访问关系型数据库一种通用语言,它属于第四代语言( 4GL ),其执行特点是非过程化,即不用指明执行的具体方法和途径,而是简单的调用相应语句来直接取得结果即可。 例: delete from students where major=‘Nutrition’; 然而,对于有些复杂的业务流程又要求相应的程序来描述,那么 4GL 就有些无能为力了 。 - PowerPoint PPT Presentation

Transcript of 第一章 PL/SQL 介绍

Page 1: 第一章  PL/SQL 介绍

第一章 PL/SQL 介绍• 1.1  什么是 PL/SQL 结构化查询语言 (Structured Query Language ,简称 S

QL) 是用来访问关系型数据库一种通用语言,它属于第四代语言( 4GL ),其执行特点是非过程化,即不用指明执行的具体方法和途径,而是简单的调用相应语句来直接取得结果即可。 例: delete from students where major=‘Nutrition’; 然而,对于有些复杂的业务流程又要求相应的程序来描述,那么 4GL 就有些无能为力了。 PL/SQL 通过增加了用在其它过程性语言中的结构来对 SQL 进行了扩展,使得它不仅仅是一个数据库查询语言,而且也是一个编程语言。

Page 2: 第一章  PL/SQL 介绍

PL/SQL 代表面向过程化的语言与 SQL 语言的结合,在编写 PL/SQL 代码时可以在 SQL 语句中使用:(1) 变量和类型(2) 控制语句(3) 过程和函数(4) 对象类型和方法

PL/SQL 语言实现了将过程结构与 Oracle SQL 的无缝集成例:修改一个学生的专业,如果没有该学生,就插入一个新的记录--3gl_4gl.sqlDECLARE v_newmajor VARCHAR2(10):=‘History’; v_firstname VARCHAR2(10):=‘Scott’; v_lastname VARCHAR2(10):=‘Urman’;

Page 3: 第一章  PL/SQL 介绍

BEGIN update students set major=v_newmajor where first_name=v_last_name and last_na

me=v_last_name;

If SQL%notfound then insert into students(ID,FIRST_NAME,LAST_NA

ME,MAJOR) VALUES (student_sequence.NEXTVAL,v_firstname,

v_lastname,v_newmajor); End if;End;

Page 4: 第一章  PL/SQL 介绍

PL/SQL 与网络传输Oracle 数据库服务器

SQL SQL SQL

客户应用

Oracle 数据库服务器

客户应用

SQL

SQL

SQL

使用 SQL 使用 PL/SQL

在执行期间,将所有的 SQL 语句传递给 SQL 语句执行器组件执行。相对于逐条发送一组 SQL 语句, PL/SQL 的打包传输,减少网络流量。

Page 5: 第一章  PL/SQL 介绍

• 1.2   PL/SQL  功能特性 1.2.1 PL/SQL 的程序结构  PL/SQL 程序都是以块( block )为基本单位。 DECLARE

变量、常量、游标、自定义异常 BEGIN SQL 语句 PL/SQL 控制语句 EXCEPTION 错误发生时执行的动作 END ; 整个 PL/SQL 块分三部分:声明部分(用 declare 开头)、执行部分(以 begin 开头)和异常处理部分(以 exception 开头)。其中执行部分是必须的,其他两个部分可选。

Page 6: 第一章  PL/SQL 介绍

/* 声明部分,以 declare 开头 */declare v_id integer;v_name varchar(20);cursor c_emp is select * from employee where emp_id=3;

/* 执行部分,以 begin 开头 */begin   open c_emp;     -- 打开游标  loop   fetch c_emp into v_id,v_name;   -- 从游标取数据   exit when c_emp%notfound ;  end loop ;close c_emp;            -- 关闭游标dbms_output.PUT_LINE(v_name);

/* 异常处理部分,以 exception 开始 */exception  when no_data_found then    dbms_output.PUT_LINE(' 没有数据 ');end ;

Page 7: 第一章  PL/SQL 介绍

1.2.2 变量声明与赋值 在大多数 PL/SQL 块中,都需要使用变量来包含在程序逻辑中使用的值。无论需要什么类型的变量,能够在 BEGIN 部分中使用它之前,都必须在块的 DECL

ARE 段中声明这些变量。 声明变量必须提供变量名称和数据类型。 变量名称遵循以下约定: ( 1 )以一个字母字符开头 ( 2 )最多包含 30 个字符 ( 3 )可以包含大写和小写字母、数字以及 _ 、 $ 、 # 及其它特殊字符。

Page 8: 第一章  PL/SQL 介绍

( 1 ) PL/SQL 的基本数据类型 BINARY_INTEGER NUMBER[(precision,scale)] CHAR[(maximum_length)] LONG LONG RAW VARCHAR2(maximum_length) DATE BOOLEAN

Page 9: 第一章  PL/SQL 介绍

声明变量的语法:变量名 类型〔 constant 〕 [not null] [:=value];

注意:在声明部分,每一行只能有一个变量声明,如以下的声明是错误的: Declare

v_firstname , v_lastname varchar2(20);

正确的声明为: Declare

v_firstname varchar2(20);

v_last_name varchar2(20);

Page 10: 第一章  PL/SQL 介绍

变量的初始化: Declare

v_description varchar2(50);

v_numberseats number:=45;

v_counter binary_integer:=0;

注意:后面跟一个值的: = 用来向声明语句中的变量来指定初始值。也可以使用 default 替代: = 符号。 Declare

v_numberseat number default 45;

Page 11: 第一章  PL/SQL 介绍

另外还可以在变量中加入 NOT NULL 和 CONSTANT 。declare

C_minimunstudentid constant number(5):=10000;

如果变量在声明时使用了 constant, 则该变量应被初始化,且以后不能改变它的值。 如果在声明时指明 not null ,那么应该给该变量赋初值,下面声明是错误的: Declare

v_tempvar number not null;

正确的声明为: Declare

v_tempvar number not null:=1;

注意: CONSTANT 关键字是在变量类型之前列出的,而 NOT NULL 是在数据类型之后列出的。

Page 12: 第一章  PL/SQL 介绍

使用 DBMS_OUTPUT 检查变量值:( 1 )打开 SQL*PLUS 并登录( 2 ) set serveroutput on

( 3 ) declare

lv_basket_date date:=sysdate;

begin

dbms_output.put_line(lv_basket_date );

end;

Page 13: 第一章  PL/SQL 介绍

另外还可以在 PL/SQL 块中包括 SQL : declare

lv_qty_num number(3);

begin

select count(*) into lv_qty_num

from emp;

dbms_output.put_line(lv_qty_num );

End;

Page 14: 第一章  PL/SQL 介绍

PL/SQL 的复合数据类型 标量变量非常有用,但很多时候,需要处理逻辑的数据组,于是 PL/SQL 提供了复合的数据类型,允许创建一个变量,可以将不同数据类型的多个值存储为一个单独的单元。把复合数据类型分为两种:( 1 )复合数据类型:主要是记录数据类型和记录表类型( 2 )集合数据类型:主要是按索引组织表类型、嵌套表类型和数组类型。

这两者之间的区别是,复合变量包含多种数据类型,而集合则包含相同数据类型的多个值。

Page 15: 第一章  PL/SQL 介绍

记录数据类型: 记录数据类型和表的行结构非常相似,一行数据通常包括许多不同的字段。就一个记录变量而言,必须使用 TYPE 语句来创建自己的数据类型。TYPE 语句的语法格式如下: Type record_type is record(

field1 type1 [not null]:=expr1;

field2 type2 [not null] :=expr2;

…)

Page 16: 第一章  PL/SQL 介绍

例:Type t_StudentRecord is RECORD( StudentID NUMBER(5), FirstName VARCHAR2(20), LastName VARCHAR2(20));V_StudentInfo t_StudentRecord;

当引用记录中的一个字段时,用点标记,其语法为:Record_name.filed_name例: v_StudentInfo.FistName:=‘john’;

记录赋值 如果要将一个记录赋值给另一个记录,则这两个记录要类型完全相同。

Page 17: 第一章  PL/SQL 介绍

如:declare v_sample1 t_StudentRecord; v_sample2 t_StudentRecord;Begin v_sample1:=v_sample2;..End;

甚至尽管两个类型包含相同的字段定义,但是这两个类型完全不同, 这样类型的记录,彼此之间也不能赋值。下例是非法的Declare TYPE t_RecType1 is RECORD( Field1 number, Field2 VARCHAR(5)); TYPE t_RecType2 is RECORD( Field1 number, Field2 VARCHAR2(5));

Page 18: 第一章  PL/SQL 介绍

v_Rec1 t_RecType1; v_Rec2 t_RecType2 ;Begin v_Rec1:=v_Rec2; -- 非法 v_Rec1.Field1:=v_Rec2.Field1; -- 合法 v_Rec1.Field2:=v_Rec2.Field2; -- 合法End;

也可以使用 select 语句对记录进行赋值,记录中的字段应该与查询选择结果列表的字段相匹配例:Declare TYPE t_StudentRec is RECORD( FirstName students.first_name%type, LastName students.last_name%type, Major students.major%type);

Page 19: 第一章  PL/SQL 介绍

v_Student t_StudentRec ;Begin SELECT first_name,last_name,major into v_Student FROM students WHERE id=10000;End;(select 语句中的列顺序与在记录变量中的字段顺序一致)

• %TYPE 和% ROWTYPE 使用 %TYPE 属性

%type 用于变量类型的声明中。也可以用于保证定义的变量的数据类型和长度与数据库表中的列保持一致。例:Declare v_vxm treader.vxm%type;

Page 20: 第一章  PL/SQL 介绍

使用 %ROWTYPE 属性定义记录类型为 表名% rowtype ,则返回和数据表一样类型的记录行。例:

Declare v_roomrecord rooms%rowtype;则 v_roomrecord 将与表 rooms 有相同的结构。如果表的定义改变了,则记录的类型也随之改变。

Page 21: 第一章  PL/SQL 介绍

记录表类型记录表是另外一种复合数据类型。为什么需要记录表呢?Declare

iv_basket_num number(3);

iv_created_date date;

Begin

select idbasket,dtcreated into iv_basket_num, iv_created_date

from bb_basket;

Dbms_output.put_line(iv_basket_num||’*’|| iv_created_date );

End;

如果查询语句返回值有多个,则会出现错误“ exact fetch returns more than requested numbers of rows” 。因为 into子句中的变量不能处理多行数据。

Page 22: 第一章  PL/SQL 介绍

需要有一个可以存储多个行以及多个字段的变量(记录表类型)例:Declare

type type_basketitems is table of bb_basketitem%rowtype

index by binary_integer;

Tbl_basketitems type_basketitems;

Begin

Tbl_basketitems(1).idproduct:=1;

Tbl_basketitems(1).price:=10.8;

Tbl_basketitems(1).quantity:=2;

Tbl_basketitems(1).option1:=2;

End;

Page 23: 第一章  PL/SQL 介绍

集合数据类型 “集合”是一个已排序的元素组,它允许将相同数据类型的多个值作为一个单独的单元来处理。“集合”有三种:按索引组织的表;数组、嵌套表。( 1 )按索引组织的表 它是一种可以处理多行数据但是只能处理一个字段的变量。除了只包含单独的一列数据之外,按索引组织的表在本质上与记录表是相同的。 声明按索引组织的表的数据类型与声明记录表数据类型非常相似。首先创建一种数据类型(包含一列的表结构和一个引用行的索引),其次,使用这种数据类型声明一个表。如:Declare

type type_roast is table of number

index by binary_integer;

tbl_roast type_roast ;

Begin

tbl_roast(1):=6.22; /*因为按索引组织的表变量中只有一个单独的列是可用的,所以在将一个值 */

tbl_roast(2):=6.13; /* 输入到这种变量中时,只需要指出行号即可 */

tbl_roast(3):=6.27;

End;

Page 24: 第一章  PL/SQL 介绍

注意: ( 1 )按索引组织的表并不是数据库中实际存在的表。它们是一些变量,用来存储和操作 PL/SQL 程序中的数据。因此,不能在这些表上执行 SQL命令。( 2 )按索引组织的表具有“表属性”。“表属性”是可以和表变量一起使用的函数,它允许更好地处理表的值。属性名称 数据类型 说明count number 表中的行数delete 无 从表中删除一行exists boolean 如果指定的行存在,为 true

first Binary_integer 表中第一行的索引last Binary_integer 表中最后一行的索引next Binary_integer 在指定行之后,表中下一行的索引prior Binary_integer 在指定行之后,表中上一行的索引

Page 25: 第一章  PL/SQL 介绍

例:Declare

type type_roast is table of number

index by binary_integer;

tbl_roast type_roast ;

Lv_avg_num number;

Begin

tbl_roast(1):=6.22;

tbl_roast(2):=6.13;

tbl_roast(3):=6.27;

Lv_avg_num:= tbl_roast . count;

Dbms_output.put_line(Lv_avg_num);

End;

Page 26: 第一章  PL/SQL 介绍

( 2 )嵌套表  嵌套表是表中之表。一个嵌套表是某些行的集合,它在主表中表示为其中的一列。对主表中的每一条记录,嵌套表可以包含多个行。 例:假设有一个关于动物饲养员的表,希望其中具有他们饲养的动物的信息。用一个嵌套表,就可以在同一个表中存储饲养员和其饲养的全部动物的信息。 步骤 1 :创建类型 animal_ty :此类型中,对于每个动物都包含有一个记录,记载了其品种、名称和出生日期信息。 CREATE TYPE animal_ty AS OBJECT (breed varchar2(25), name varchar2(25), birthdate date);

Page 27: 第一章  PL/SQL 介绍

步骤 2 :创建 animals_nt :此类型将用作一个嵌套表的基础类型。 CREATE TYPE animals_nt as table of animal_ty;

步骤 3 :创建表 breeder :饲养员的信息表 create table breeder

(breedername varchar2(25),animals animals_nt)nested table animals store as animals_nt_tab;

Page 28: 第一章  PL/SQL 介绍

步骤 4 :向嵌套表中插入记录insert into breeder values('mary',animals_nt(animal_ty('dog','butch','970304'),animal_ty('dog','rover','970405'),animal_ty('dog','julio','970506')));insert into breeder values('jane',animals_nt(animal_ty('cat','an','970304'),animal_ty('cat','jame','970405'),animal_ty('cat','killer','970808')));步骤 5:查询嵌套表 select name,birthdate from table(select animals from breeder);

select name,birthdate from table(select animals from breeder where breedername=’mary’) where name=’dog’;

Page 29: 第一章  PL/SQL 介绍

( 3 )可变数组 可变数组与嵌套表相似,也是一种集合。一个可变数组是对象的一个集合,其中每个对象都具有相同的数据类型。可变数组的大小由创建时决定。在表中建立可变数组后,可变数组在主表中作为一个列对待。从概念上讲,可变数组是一个限制了行集合的嵌套表。例:步骤 1 :创建类型 comm_info

CREATE TYPE comm_info AS OBJECT ( /* 此类型为通讯方式的集合 */no number(3), /* 通讯类型号 */comm_type varchar2(20), /* 通讯类型 */comm_no varchar2(30)); /* 号码 */

步骤 2 :创建可变数组 comm_info_list

CREATE TYPE comm_info_list AS VARRAY(50) OF comm_info;步骤 3 :创建表

Page 30: 第一章  PL/SQL 介绍

create table user_info(user_id number(6), /*用户 ID号 */user_name varchar2(20), /*用户名称 */user_comm comm_info_list); /*与用户联系的通讯方式 */步骤 4:向可变数组插入记录 insert into user_infovalues(1,'mary',comm_info_list(comm_info(1,' 手机 ','13651401919'),comm_info(2,‘呼机’ ,‘1281234567’)));

insert into user_infovalues(2,'carl',comm_info_list(comm_info(1,' 手机 ','13901018888'),comm_info(2,' 呼机 ','1281234567')));

Page 31: 第一章  PL/SQL 介绍

步骤 5 :查询可变数组 select user_comm from user_info where user_id=1;

select comm_type,comm_no from table(select user_comm from user_info where user_id=1)where no=1;

Page 32: 第一章  PL/SQL 介绍

绑定变量(主机变量)变量名称前加上冒号告诉 PL/SQL 这是一个主机变量,如: where idshopper=:g_shopper

and orderplaced=0;

使用 variable命令来创建主机变量。注意, variable命令创建的主机变量是SQL*PLUS 变量,不是 PL/SQL 变量。主机变量的类型是 number,char 和 varchar2 ,没有 date 和 boolean 类型。( 1 )在 SQL*PLUS 中输入 variable g_shopper number

(注意末尾没有 ; 号)( 2 ) begin

: g_shopper :=25;

End;

Page 33: 第一章  PL/SQL 介绍

变量的作用域和可见性变量的作用域是可以访问该变量的程序部分。 PL/SQ

L 变量的作用域为从声明部分开始到块的结束。当一个变量超出了作用域, PL/SQL 将释放变量的空间。例

Declare v_number(3,2);Begin declare v_character varchar2(10); begin … end;End;

Page 34: 第一章  PL/SQL 介绍

变量的可见性是可以访问变量而不必保证该变量的引用是否有效的程序部分。可见性始终在作用域内。如果一个变量超出了作用域范围,就不可见了。例:Declare

v_availableflag boolean; v_ssn number(9);Begin (1) declare v_ssn char(11); v_startdate date; begin (2) end; (3)End;

V_availableflag 和 number(9) 的 v_ssn 可见V_availableflag 和 char(11) 的 v_ssn , v_

startdate 可见V_availableflag 和 num

ber(9) 的 v_ssn 可见

Page 35: 第一章  PL/SQL 介绍

如果一个变量在作用域内,但不可见,可以使用标签加以引用变量。

<<outer>>Declare

v_availableflag boolean; v_ssn number(9);Begin (1) declare v_ssn char(11); v_startdate date; begin (2) end; (3)End;

V_availableflag 和 number(9) 的 v_ssn 可见

V_availableflag 和 number(9) 的 v_ssn 可见

V_availableflag 和 char(11) 的 v_ssn , v_startdate 可见,通过outer.v_ssn 引用 num

ber(9) 的 v_ssn

Page 36: 第一章  PL/SQL 介绍

• PL/SQL 表达式赋值

语法: 变量 := 表达式;在一个特定的 PL/SQL 语句中仅能够有一个赋值。下面的例子是错误的。

V_val1:=v_val2:=v_val3:=0;表达式

表达式作为一个句子是无效的,他必须是一条语句的一部分,是右值。 字符表达式 : || 运算符

Page 37: 第一章  PL/SQL 介绍

运算符的优先级 优先级 运算符 描述1 ** 乘方2 +、- 正负号3 * 、 / 乘除4 + 、 - 、 || 加减、字符串连接5 = 、 < 、 > 、 <= 、 >= 、 != 、

~= 、 ^= 、 is null 、 like 、 between 、 in

比较

6 Not 逻辑非7 And 逻辑与8 Or 逻辑或

Page 38: 第一章  PL/SQL 介绍

布尔表达式 :NULL 为布尔表达式添加了复杂性。True and null 结果为 null仅当操作数是 null 时, is null才返回 true 。不能用关系运算符对 null 值进行检测。Like , between and , in 返回的值为 boolean 类型。

1.算术形式的布尔表达式Number1>number2

2.字符形式的布尔表达式String1>string2

3.日期形式的布尔表达式Date1=’01-jan-91’;Date2=’31-dec-90’;Data1>date2

Page 39: 第一章  PL/SQL 介绍

4.一些注意事项(1)不要在实数之间比较相等,因为实数作为近似值存储。如,下例表达式可能不为 trueDeclare number1:=1;Begin if number1=1.0 then dbms_output.put_line(‘dskjhds’); End if;End;(2)比较时用圆括号较好(3)当使用 CLOB 的值作为比较运算符的操作数时,或者用在 LIKE 和 BETWEEN子句中,结果集会产生一个临时的 LOBS ,要确定临时存储空间够用

Page 40: 第一章  PL/SQL 介绍

1.2.3   pl/sql 的程序控制结构 PL/SQL 程序段中有三种程序结构:条件结构、循环结构和顺序结构。 ( 1 )条件结构 : if condition then

statement1 else statement2end if ;

( 2 ) 循环结构 : 与其他语言不太一样,在 PL/SQL 程序中有三种循环结构:

Page 41: 第一章  PL/SQL 介绍

a: loop … end loop;

b. while condition loop … end loop;

c. for variable in low_bound . . upper_bound loop … end loop;

其中的“…”代表循环体。 例: loop循环 (simpleloop.sql)

Declare

v_loopcounter binary_integer:=1;

Begin

loop

insert into temp_table (num_col) values (v_loopcounter);

v_loopcounter:=v_loopcounter+1;

exit when v_loopcounter>50;

end loop;

End;

Page 42: 第一章  PL/SQL 介绍

例: for循环 Begin

for v_loopcounter in 1..50 loop

insert into temp_table(num_col) values (v_loopcounter);

end loop;

End;

( 3 )顺序结构 实际就是 goto的运用,不过从程序控制的角度来看,尽量少用 goto可以使得程序结构更加的清晰。

Page 43: 第一章  PL/SQL 介绍

4、 SQL基本命令 PL/SQL使用的数据库操作语言还是基于 SQL的,所以熟悉 SQL是进行 PL/SQL编程的基础。下表为 SQL语言的分类。

类别 SQL 语句数据定义语言 (DDL) Create ,Drop,Grant,Revoke, …数据操纵语言 (DML) Update,Insert,Delete, …

数据控制语言 (DCL) Commit,Rollback,Savapoint, …其他 Alter System,Connect,Allocate, …

Page 44: 第一章  PL/SQL 介绍

1.2.4  游标 游标在 PL/SQL的编程中非常的重要。其定义为:用游标来指代一个 DML SQL 操作返回的结果集。即当一个对数据库的查询操作返回一组结果集时,用游标来标注这组结果集,以后通过对游标的操作来获取结果集中的数据信息。 定义游标的语法结构如下: cursor cursor_name is SQL 语句 ;

例: cursor c_emp is select * from employee where emp_id=3;

Page 45: 第一章  PL/SQL 介绍

当需要操作该结果集时,必须完成三步:打开游标、使用 fetch语句将游标里的数据取出、关闭游标。例: Declare

v_first_name varchar2(20);

V_last_name varchar2(20);

Cursor c_student is select first_name, last_name from students;

Begin open c_students; loop fetch c_students into v_firstname, v_last_name; exit when c_students%notfound;end loop;close c_students;End;

Page 46: 第一章  PL/SQL 介绍

1.2.5 过程和函数  PL/SQL中的过程和函数与其他语言的过程和函数的概念一样,都是为了执行一定的任务而组合在一起的语句。过程无返回值,函数有返回值。其语法结构为: 过程:Create or replace procedure procname( 参数列表 ) as PL/SQL语句块 函数:Create or replace function funcname( 参数列表 ) return 返回值 as PL/SQL语句块

Page 47: 第一章  PL/SQL 介绍

例:假设有一张表 t1,有 f1和 f2两个字段, f1为 number类型, f2为 varchar2类型,然后往 t1里写两条记录,内容自定。 Create or replace procedure test_procedure as V_f11 number :=1; /* 声明变量并赋初值 */V_f12 number :=2;V_f21 varchar2(20) :=’first’;V_f22 varchar2(20) :=’second’;BeginInsert into t1 values (V_f11, V_f21);Insert into t1 values (V_f12, V_f22);End test_procedure; /*test_procedure 可以省略 */

至此, test_procedure存储过程已经完成,编译后存储在数据库中,然后可以在其他PL/SQL块或者过程中调用了。 Sql>begin

2 test_procedure;

3 end;

Page 48: 第一章  PL/SQL 介绍

1.2.6 包 PL/SQL 的过程和函数可以和变量与类型共同组成包。 PL/SQL 的包由两部分组成,即说明部分和包体。例: roompkg.sqlCreate or replace package roomspkg as procedure newroom(p_building rooms.building

%type, p_roomnum rooms.room_n

umber%type, p_description rooms.descriptio

n%type); Procedure deleteroom(p_roomid in rooms.room_

id%tye);End roomspkg;

Page 49: 第一章  PL/SQL 介绍

Create or replace package body roompkg as procedure newroom(p_building rooms.building%type, p_roomnum rooms.room_number

%type, p_description rooms.description%typ

e) is begin insert into rooms (room_id,building,room_nu

mber,number_seats,description) values (room_sequence.nextval,p_building,p_roomn

um,p_numseats,p_description);End newroom;Procedure deleteroom(p_roomid in rooms.room_id%tye)

isbegin delete from rooms where room_id=p_roomid; end deleteroom;End roompkg;

Page 50: 第一章  PL/SQL 介绍

1.2.7  动态 SQL借助于动态 SQL ,可以在运行期间构造并执行 SQL 语句。使用动态 SQL 语句有两种方法,一种是使用 DBMS_SQL包,另一种是使用 Oracle8i支持的本地动态 SQL 。例: printstudents.sqlCreate or replace procedure droptable(p_tabl

e in varchar2) as v_sqlstring varchar2(100);Begin v_sqlstring:=‘drop table ‘ || p_table; execute immediate v_sqlstring;End droptable;

Page 51: 第一章  PL/SQL 介绍

例: droptable.sqlCreate or replace procedure droptable(p_table i

n varchar2) as v_sqlstring varchar2(100); v_cursor binary_integer;V_returncode binary_integer;Begin v_sqlstring:=‘drop table ‘ || p_table;--open the cursor. V_cursor:=dbms_sql.open_cursor;--parse and execute the statement. Dbms_sql.parse(v_cursor,v_sqlstring,dbms_s

ql.native);V_returncode:=DBMS_SQL.EXECUTE(v_cur

sor);--close the cursor. Dbms_sql.close_cursor(v_cursor);End droptable;

Page 52: 第一章  PL/SQL 介绍

1.2.8 对象类型对象类型由属性和方法组成,并可存储在数据库表中。例: ch12/objtypes.sqlCreate or replace type student as object( id number(5), first_name varchar2(20), last_name varchar2(20), major varchar2(30), current_credits number(3),--return the first and last namesMember function formattedname return varchar2,Pragma restrict_references(formattedname,RNDS,WNDS,RNPS,WNPS),

Page 53: 第一章  PL/SQL 介绍

--updates the major to the specified value in p_newmajor

MEMBER PROCEDURE changemajor(p_newmajor in varchar2),

PRAGMA RESTRICT_REFERENCES(changemajor,RNDS,WNDS,RNPS,WNPS),

--updates the current_credits by adding the n

umber of--credits in p_completedclass to the current v

alue.MEMBER PROCEDURE updatecredits(p_c

ompletedclass in class),PRAGMA RESTRICT_REFERENCES(upd

atecredits,RNDS,WNDS,RNPS,WNPS),

Page 54: 第一章  PL/SQL 介绍

--order function used to sort students.Order member function comparestudent(p_student in s

tudent) return number);

Create or replace type body student as member function formattedname return varchar2 is begin return first_name || ‘ ‘ ||last_name; end formattedname;

Page 55: 第一章  PL/SQL 介绍

Member procedure changemajor(p_newmajor in varchar2) is

begin major:=p_newmajor; End changemajor; member procedure updatecredits(p_completedcl

ass in class ) is begin current_credits:=current_credits+ p_completedclass.num_credits;End updatecredits;

Page 56: 第一章  PL/SQL 介绍

Order member function comparestudent(p_student in student)

return number isBegin --first compare by last name if p_student.last_name=self.last_name then if p_student.first_name<self.first_name then return 1; elseif p_student.first_name>self.first_name

then return –1; else return 0; end if; else

Page 57: 第一章  PL/SQL 介绍

if p_studen.last_name<selef.last_name then return 1; else return –1; end if; end if;End comparestudent;End;

Page 58: 第一章  PL/SQL 介绍

• PL/SQL 风格指南注释风格

在每个块和过程的开始放注释,解释该块的功能,特别是列出过程的输入、输出参数和引用的数据库在每个变量的旁边添加单行注释,说明该变量的作用。在块的每个主要部分之前添加注释。最好说明算法的目的和结果。而不是对该代码进行过多细节的说明。

变量名风格:变量名应该告示变量的用途。最大长度 20个字符。例:v_variablename program variableE_exceptionname user_defined exceptionT_typename user_defindex typeP_parametename parameter or procedure or functi

onC_constantvalue constant constrained with the cons

tant clauses

Page 59: 第一章  PL/SQL 介绍

大写风格保留字使用大写字母内置函数使用大写字母预定义类型使用大写字母( NUMBER(7,2))SQL 关键字使用大写字母( INSERT )数据库对象使用小写变量名使用大小写混合,名字中每个单词开头大写( t_StudentRecordType )

缩进风格在每个块以内缩进两个空格。在 declare…end 之间进行缩进, if-then-else内也进行缩进,在多行上连续的 SQL 语句上也进行缩进。如:

Select id,first_name,last_name into v_StudentID,v_FirstName,v_LastName from students where id=1002;

Page 60: 第一章  PL/SQL 介绍

• 1.6 本书案例使用的通用数据库表序列

Student_sequence: 生成 students 主键的唯一值Create sequence student_sequence start with 10000 increment by 1;

Room_sequenceCreate sequence room_sequence start with 20000 increment by 1;

Page 61: 第一章  PL/SQL 介绍

表Students: 入学新生的信息

Create table students ( id number(5) primary key, first_name varchar2(20), last_name varchar2(20), major varchar2(30), current_credits number(3));Insert into students(id,first_name,last_name,

major,current_credits)Values (student_sequence.nextval,’Margare

t’,’Mason’,’History’,4);

Page 62: 第一章  PL/SQL 介绍

Major_stats :不同专业的统计信息Create table major_stats( major varchar2(30), total_credits number, total_students number);Insert into major_stats (major,total_credits,to

tal_students) values (‘computer science’,22,3);

Page 63: 第一章  PL/SQL 介绍

Rooms: 可用的教室信息Create table rooms( room_id number(5) primary key, building varchar2(15), room_number number(4), number_seats number(4), Description varch2(50));

Insert into rooms (room_id,building,room_number,number_seats,

description)Values (room_sequence.nextval,’Building 7’,

201,1000,’large lecture hall’);

Page 64: 第一章  PL/SQL 介绍

Classes: 学生可以选择的课程Crete table classes( department char(3), course number(3), description varchar2(2000), max_students number(3), current_students number(3),Num_credits number(1),Room_id number(5),Constraint classes_department_course primary key (department,course),Constraint classes_room_id foreign key(room_id) references rooms (room_id));Insert into classes(department,course,description,max_st

udents, current_students,num_credits,room_id)Values (‘His’,101,’History 101’,20,11,4,20000);

Page 65: 第一章  PL/SQL 介绍

Registered_students: 学生目前参加的课程信息Create rtable registered_students( student_id number(5) not null, department char(3) not null, course number(3) not null, grade char(1), constraint rs_grade check (grade in (‘A’,’B’,’C’,’D’,’E’)),Constraint rs_student_id foreign key(student_id) references students (id),Constraint rs_department_course foreign key(department,course) references classe

s(department,course));Insert into registered_students (student_id,departm

ent,course,Grade) Values (10000,’CS’,102,’A’);

Page 66: 第一章  PL/SQL 介绍

Rs_audit: 记录对表 registered_students 所作的修改Create table rs_audit ( change_type char(1) not null, chaged_by varchar2(8) not null, timestamp DATE not null,Old_student_id number(5), old_department char(3), old_course number(3), old_grade char(1), new_student_id number(5), new_department char(3), new_course number(3), new_grade char(1));

Page 67: 第一章  PL/SQL 介绍

Log_table: 记录 oracle 数据库发生的错误信息Create table log_table( code number, Message varchar2(200), info varchar2(100));

Temp_table: 存放临时数据Create table temp_table( num_col number, char_col varchar2(60));

Connect_audit: 记录与数据库的连接和断开信息Create table connect_audit ( user_name varchar2(30)., operation varchar2(30), timestamp DATE);

Page 68: 第一章  PL/SQL 介绍

Debug_table:保存 PL/SQL 的调试信息Create table debug_table( linecount number, debug_str varchar2(100));

Source: 第三章中调试程序案例使用的Create table source( key number(5), value varchar2(50));

Destination: 第三章中调试程序案例使用的Create table destination( key number(5), value varchar2(50));