1、PL/SQL定义

PL/SQL也是一种程序语言,叫做过程化SQL语言(Procedural Language/SQL)。PL/SQL是Oracle数据库对SQL语句的扩展。在普通SQL语句的使用上增加了编程语言的特点,所以PL/SQL就是把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算的程序语言。

2、记录

(1)记录是一种复合数据结构,它由一到多个字段组成。

(2)PL/SQL中的记录大致等同于数据库表中的行。
(3)可用任何指定结构创建记录,与特定的表和游标完全无关

2.1 记录的好处

(1)数据抽象:不用与实体或对象的单独属性打交道,而是将实体作为“独立”的对象来操作;

(2)聚合操作:可以执行影响记录中所有列的操作;
(3)简洁、情绪的代码:能编写更少的代码,并且使所写的代码更易于理解;

2.2 基于表的记录

常用格式:<record_name> <table_name>%rowtype;
如:emp_rec EMP%rowtype;

2.3 基于游标的记录

常用格式:<record_name> <cursor_name>%rowtype;
如:CURSOR emp_cur IS SELECT * FROM EMP;
    emp_rec emp_cur%rowtype;

2.4 程序员定义的记录

常用格式:<record_name> <record_type>;
如:type customer_rectype is record
           (EMPNO EMP.EMPNO%type,
            ENAME EMP.ENAME%type,
            DEPTNO varchar2(100)
           );

3、PL/SQL表

概念:PL/SQL表是一维的、无边界的、由同类元素组成的稀疏集合

特点:一维(只能一列)、无边界(没有预定义的限制)、稀疏(赋值后才存在)、同类元素(因为一列,只能同类)、可作为参数进行传递

(1)PL/SQL表是驻留在内存中的对象,提供类似数组的数据访问方式,PL/SQL表中的元素没有特定的顺序,在PL/SQL表中的KEY不必是连续的

(2)稀疏的 只有行被赋予一个值后,该行才会存在于表中
(3)无限制 与数据库中的表一样,使用前无需担心大小,PL/SQL表的大小是没有限制的 
(4)数据类型要相同

3.1 先定义type

type <type名称> is table of <数据类型> [not null]
index by binary_integer;
index by binary_integer的意思是按整数编制索引

3.2 定义变量

变量名称 pl/sql表类型
test_var plsql_table_type;

4、数据类型——ROWID

(1)ROWID是一个伪列,是表的一部分,由内部产生并维护的二进制值,它标识表中的一行数据;

(2)OOOOOOFFFBBBBBBRRR
其中:
OOOOOO: 六位表示data object id,根据object id可以确定segment。
FFF: 三位表示相对文件号。根据该相对文件号可以得到绝对文件号,从而确定datafile。
BBBBBB:六位表示data block number。这里的data block number是相对于datafile的编号,而不是相对于tablespace的编号。
RRR:三位表示row number。

5、PL/SQL中的NULL

(1)一个NULL不与其他任何值相等;

(2)一个NULL不与其他任何值不等;
(3)比较操作中存在NULL值,永远不等
(4)比较NULL值,<identifier> IS NULL, <identifier> IS NOT NULL

6、ROWNUM 工作原理

ROWNUM是一个虚假的列. 它将被分配为 1, 2, 3, 4, ... N, N 是行的数量. 一个ROWNUM值不是被永久的分配给一行 (这是最容易被误解的). 表中的某一行并没有标号; 你不可以查询ROWNUM值为5的行——根本没有这个概念.

另一个容易搞糊涂的问题是ROWNUM值是何时被分配的. ROWNUM值的分配是在查询的谓词解析之后, 任何排序和聚合之前进行的. ROWNUM值只有当被分配之后才会增长. 这就是为什么下面的查询永远都不会返回结果:
     select * from countries where rownum>1;
     ROWNUM > 1对于第一行来说并不是真值, ROWNUM没有增长到 2. 所以, 没有比1大的ROWNUM.永远都不要使用'ROWNUM>?'和'ROWNUM=2…N'这样的条件.

7、匿名PL/SQL块

BEGIN

  null;
END;
说明:匿名块可以有自己的声明段和执行段,除了BEGIN和END语句外,其他内容都是可选的,也要求至少有一条可执行语句。

8、过程

说明:执行一个或多个操作的模块。可作为可执行PL/SQL语句调用一个过程,意味着调用后必须以分号结束:test(参数);也可以不带参数调用:test;注意没有括号,可别写成test();

常用格式:
--参数可以没有
CREATE OR REPLACE PROCEDURE 名字 [(参数[,参数…])]
IS
  [声明语句]
BEGIN
  可执行语句,必须有一条可执行语句
[EXCEPTION]
—没有异常处理可以通过编译
END [名字];--建议加上名字,是个好习惯

9、函数

说明:返回一个值的模块,与过程不同,对函数的调用只能是可执行语句的一部分;

常用格式:
--参数可以没有
CREATE OR REPLACE FUNCTION 名字 [(参数[,参数…])]
  RETURN return_datatype
IS
  [声明语句]
BEGIN
  可执行语句,必须有一条可执行语句
  建议在最后
[EXCEPTION]
—没有异常处理可以通过编译
END [名字]; --建议加上名字

10、包

(1)包说明:对包中所有元素的定义或说明;

(2)包体:包中所有代码的实行:模块、游标和其他对象的实现;

10.1包说明:

CREATE OR REPLACE PACKAGE package_name
IS
[变量与类型的声明]
[游标的说明]
[模块的说明]
END [package_name];

包说明中可以包括以下任意对象:

(1)变量声明(这里定义的变量可以被其他程序和PL/SQL块调用,即所谓的公共变量,包体中定义的变量为私有元素,不能被外界调用)
(2)TYPE声明
(3)异常声明
(4)游标声明
(5)模块声明(存储过程或者函数)
模块类型(存储过程或者函数)
模块名称、参数列表、RETURN子句

10.2包体:

CREATE OR REPLACE PACKAGE BODY package_name
IS
[变量与类型的声明]
[静态游标的SELECT语句]
[模块的说明]
[BEGIN]
可执行语句
[EXCEPTION]
END [package_name];

11、异常类型

异常处理就是针对错误进行处理的程序段,Oracle中的

异常处理分为系统预定义异常处理和自定义异常处理两部分。

12、触发器

触发器是一个PL/SQL块,当某些特定时间发生时,被隐含执行

触发器可以是一个数据库触发器(DML,database or system action)或者是一个应用程序触发器(Form)
常用格式
CREATE [OR REPLACE] TRIGGER trigger
{BEFORE|AFTER}
{DELETE|INSERT|UPDATE [OF column [,column]…]}
[OR{DELETE|INSERT|UPDATE [OF column [,column]…]}]…
ON table
FOR EACH ROW [WHEN condition]
BEGIN
…pl/sql block..
END [trigger]
如:
CREATE OR REPLACE TRIGGER logemp
BEFORE  INSERT OR UPDATE OR DELETE ON emp
FOR  EACH  ROW
DECLARE
statementtype CHAR(20);
BEGIN
IF INSERTING THEN
statementtype:='INSERT TRIGGER!';
ELSIF UPDATING THEN
statementtype:='UPDATE TRIGGER!';
ELSE
statementtype:='DELETE TRIGGER!';
END IF;
DBMS_OUTPUT.PUT_LINE(statementtype);
END;