PL/SQL
有自己的字符集、保留字、标点、数据类型、语法等,
它的注释采用
/**/ 来注释掉一段语句;
-- 来注释掉一行语句.
它的注释采用
/**/ 来注释掉一段语句;
-- 来注释掉一行语句.
1)、变量和常量
在PL/SQL程序中可将值存储在变量和常量中,当程序执行时,变量的值可以改变,而常量的值不能改变。
声明方法:
DECLARE
变量名 变量类型;
常量名 constant 常量类型:=常量值;
表类型 声明:
将表字段的类型映射为变量的类型。
变量名 表名.字段名%TYPE
变量名1 表名%ROWTYPE
一般在声明变量后应立刻初始化赋值.也可以在声明时直接赋值:
变量名 变量类型 :=初始值;
其中”变量名1”的使用为: 变量名1. 字段名
表类型 声明的好处是数据库结构(主要是指字段尺寸)发生变化时,不用修改相应程序.因为表类型声明的变量会在执行时重新编译,以取得真正的数据类型.
声明方法:
DECLARE
变量名 变量类型;
常量名 constant 常量类型:=常量值;
表类型 声明:
将表字段的类型映射为变量的类型。
变量名 表名.字段名%TYPE
变量名1 表名%ROWTYPE
一般在声明变量后应立刻初始化赋值.也可以在声明时直接赋值:
变量名 变量类型 :=初始值;
其中”变量名1”的使用为: 变量名1. 字段名
表类型 声明的好处是数据库结构(主要是指字段尺寸)发生变化时,不用修改相应程序.因为表类型声明的变量会在执行时重新编译,以取得真正的数据类型.
变量名:=变量值;
SELECT COL1
INTO 变量名
FROM TABLE1;
注:这种赋值方法要求TABLE1表中有且仅有一条记录。否则将报错。
SELECT COL1
INTO 变量名
FROM TABLE1;
注:这种赋值方法要求TABLE1表中有且仅有一条记录。否则将报错。
3)程序块式结构:
DECLARE
变量说明部分;
BEGIN
执行语句部分;
[EXCEPTION
例外处理部分;]
END;
变量说明部分;
BEGIN
执行语句部分;
[EXCEPTION
例外处理部分;]
END;
4)控制语句:
分支语句:
IF condition THEN
Sequence_of_statements;
END IF;
IF condition THEN
Sequence_of_statement1;
ELSE
Sequence_of_s tatement2;
END IF;
IF condition1 THEN
Sequence_of_statement1;
ELSIF condition2 THEN
Sequence_of_statement2;
ELSIF condition3 THEN
Sequence_of_statement3;
END IF;
IF condition THEN
Sequence_of_statements;
END IF;
IF condition THEN
Sequence_of_statement1;
ELSE
Sequence_of_s tatement2;
END IF;
IF condition1 THEN
Sequence_of_statement1;
ELSIF condition2 THEN
Sequence_of_statement2;
ELSIF condition3 THEN
Sequence_of_statement3;
END IF;
5) 控制语句:
循环语句:
LOOP
Sequence_of_statements;
IF condition THEN
EXIT;
END IF;
END LOOP;
WHILE condition LOOP
Sequence_of_statements;
END LOOP;
FOR counter IN lower_bound..higher_bound LOOP
Sequence_of_statements;
END LOOP;
LOOP
Sequence_of_statements;
IF condition THEN
EXIT;
END IF;
END LOOP;
WHILE condition LOOP
Sequence_of_statements;
END LOOP;
FOR counter IN lower_bound..higher_bound LOOP
Sequence_of_statements;
END LOOP;
6)数组的声明
PL/SQL
表与其他过程化语言(如C语言)的一维数组类似。实现PL/SQL表需要创建一个数据类型并另外进行变量说明,不需要事先定义数组大小。
Type < 类型名> Is
Table Of < 数据类型>
Index by Binary_Integer;
以下为一个例子:
Declare
Type Array_type is
Table Of Number
Index by Binary_Integer; -- 数组类型的声明
My_Array Array_type; -- 数组变量的定义
Begin
For I In 1..10 Loop
My_Array (I) := I*2; -- 数组的初始化
End Loop;
For I In 1..10 Loop
DBMS_OUTPUT.Put_line(To_char(My_Array(I)));
End Loop;
End;
Type < 类型名> Is
Table Of < 数据类型>
Index by Binary_Integer;
以下为一个例子:
Declare
Type Array_type is
Table Of Number
Index by Binary_Integer; -- 数组类型的声明
My_Array Array_type; -- 数组变量的定义
Begin
For I In 1..10 Loop
My_Array (I) := I*2; -- 数组的初始化
End Loop;
For I In 1..10 Loop
DBMS_OUTPUT.Put_line(To_char(My_Array(I)));
End Loop;
End;
语法:
WHEN 异常类型1 THEN
STATEMENTS;
WHEN 异常类型2 THEN
STATEMENTS;
.....
WHEN OTHERS THEN
STATEMENTS;
每个WHEN 语句指一个异常处理。OTHER语句允许定义其他WHEN语句没有定义的异常处理。在一个块语句中只允许有一个WHEN OTHERS语句。.
可以使用SQLCODE函数查看异常值。
使用SQLERRM函数查看异常信息。
使用RAISE_APPLICATION_ERR(错误号,错误消息);函数可以在EXCEPTION中使用自定义的异常来替换系统异常。
WHEN 异常类型1 THEN
STATEMENTS;
WHEN 异常类型2 THEN
STATEMENTS;
.....
WHEN OTHERS THEN
STATEMENTS;
每个WHEN 语句指一个异常处理。OTHER语句允许定义其他WHEN语句没有定义的异常处理。在一个块语句中只允许有一个WHEN OTHERS语句。.
可以使用SQLCODE函数查看异常值。
使用SQLERRM函数查看异常信息。
使用RAISE_APPLICATION_ERR(错误号,错误消息);函数可以在EXCEPTION中使用自定义的异常来替换系统异常。
8)自定义ORACLE错误码名称:
oracle
错误码有几百个,但只有最常用的几十个有名称.可以给oracle错误码起名
例:
DECLARE
BAD_ROWID EXCEPTION;
X ROWID;
PRAGMA EXCEPTION_INIT(BAD_ROWID,-01445);
-- 错误号” -01445”被命名为(BAD_ROWID
BEGIN
SELECT ROWID INTO X FROM TAB
WHERE ROWNUM=1;
EXCEPTION
WHEN BAD_ROWID THEN
DBMS_OUTPUT.PUT_LINE('CA NNOT QUERY ROWID FROM THIS VIEW');
END;
注意:-01445 因为PRAGMA EXCEPTION_INIT命令把这个变量(-01455)连接到这个ORACLE错误,该语句的语法如下:
PRAGMA EXCEPTION_INIT(exception_name, error_number);
其中error_number是负数,因为错误号被认为负数,当定义错误时记住使用负号
例:
DECLARE
BAD_ROWID EXCEPTION;
X ROWID;
PRAGMA EXCEPTION_INIT(BAD_ROWID,-01445);
-- 错误号” -01445”被命名为(BAD_ROWID
BEGIN
SELECT ROWID INTO X FROM TAB
WHERE ROWNUM=1;
EXCEPTION
WHEN BAD_ROWID THEN
DBMS_OUTPUT.PUT_LINE('CA NNOT QUERY ROWID FROM THIS VIEW');
END;
注意:-01445 因为PRAGMA EXCEPTION_INIT命令把这个变量(-01455)连接到这个ORACLE错误,该语句的语法如下:
PRAGMA EXCEPTION_INIT(exception_name, error_number);
其中error_number是负数,因为错误号被认为负数,当定义错误时记住使用负号
9) 自定义异常
异常不一定必须是oracle返回的系统错误,用户可以在自己的应用程序中创建可触发及可处理的自定义异常.
DECLARE
SALARY_CODE VARCHAR2(1);
INVALID_SALARY_CODE EXCEPTION;-- 自定义异常
BEGIN
SALARY_CODE:='X';
IF SALARY_CODE NOT IN('A', 'B', 'C') THEN
RAISE INVALID_SALARY_CODE;-- 激活异常
END IF;
EXCEPTION
WHE N INVALID_SALARY_CODE THEN
DBMS_OUTPUT.PUT_LINE('INVALID SALARY CODE');
END;
DECLARE
SALARY_CODE VARCHAR2(1);
INVALID_SALARY_CODE EXCEPTION;-- 自定义异常
BEGIN
SALARY_CODE:='X';
IF SALARY_CODE NOT IN('A', 'B', 'C') THEN
RAISE INVALID_SALARY_CODE;-- 激活异常
END IF;
EXCEPTION
WHE N INVALID_SALARY_CODE THEN
DBMS_OUTPUT.PUT_LINE('INVALID SALARY CODE');
END;
属性 含量
%FOUND 布尔型属性,当最近一次该记录时成功返回,则值为TRUE
%NOTFOUND 布尔型属性,它的值总与%FOUND属性的值相反
%ISOPEN 布尔型属性,当光标是打开时返回TRUE
%ROWCOUNT 数字型属性,返回已从光标中读取的记录数
游标(CURSOR)是指向一个称为上下文相关区的区域的指针,这个区域在服务器的处理过程全局区(PGA)内,当服务器上执行了一个查询后,查询返回的记录集存放在上下文相关区,通过游标上的操作可以把这些记录检索到客户端的应用程序。
%FOUND 布尔型属性,当最近一次该记录时成功返回,则值为TRUE
%NOTFOUND 布尔型属性,它的值总与%FOUND属性的值相反
%ISOPEN 布尔型属性,当光标是打开时返回TRUE
%ROWCOUNT 数字型属性,返回已从光标中读取的记录数
游标(CURSOR)是指向一个称为上下文相关区的区域的指针,这个区域在服务器的处理过程全局区(PGA)内,当服务器上执行了一个查询后,查询返回的记录集存放在上下文相关区,通过游标上的操作可以把这些记录检索到客户端的应用程序。
1) 使用光标的基本方法
DECLARE
CURSOR A83D861_cur IS
SELECT ankKaisha ,ankManno ,
FROM A83D861;-- 光标定义
A83D861_rectype A83D861_cur%ROWTYPE ;-- 定义光标类型的变量
BEGIN
OPEN A83D861_cur ;-- 打开光标
LOOP
FETCH A83D861_cur INTO A83D861_rectype ;-- 取记录
或者 FETCH A83D861_cur INTO lv_ankKaisha ,lv_ankManno;
EXIT WHEN A83D861_cur%NOTFOUND ;
-- 记录取完退出loop循环
………… 处理语句
END LOOP ;
CLOSE A83D861_cur ;-- 关闭光标
或者
FOR C_ A83D861_cur IN A83D861_cur LOOP
C_ A83D861_cur.COL1….
END LOOP;
END;
C_ A83D861_cur 不用声明,它被隐式声明.
CURSOR A83D861_cur IS
SELECT ankKaisha ,ankManno ,
FROM A83D861;-- 光标定义
A83D861_rectype A83D861_cur%ROWTYPE ;-- 定义光标类型的变量
BEGIN
OPEN A83D861_cur ;-- 打开光标
LOOP
FETCH A83D861_cur INTO A83D861_rectype ;-- 取记录
或者 FETCH A83D861_cur INTO lv_ankKaisha ,lv_ankManno;
EXIT WHEN A83D861_cur%NOTFOUND ;
-- 记录取完退出loop循环
………… 处理语句
END LOOP ;
CLOSE A83D861_cur ;-- 关闭光标
或者
FOR C_ A83D861_cur IN A83D861_cur LOOP
C_ A83D861_cur.COL1….
END LOOP;
END;
C_ A83D861_cur 不用声明,它被隐式声明.
存储过程,函数,包在ORACLE中被视为子程序.编译后被放入ORACLE数据字典中,用户可直接调用.
1)存储过程:
创建语法
CREATE [OR REPLACE]PROCEDURE 过程名 (in|out参数说明1,in|out参数说明2,。。。) IS
[ 局部说明]
BEGIN
执行语句;
[EXCEPTION
例外处理; ]
END 过程名;
CREATE [OR REPLACE]PROCEDURE 过程名 (in|out参数说明1,in|out参数说明2,。。。) IS
[ 局部说明]
BEGIN
执行语句;
[EXCEPTION
例外处理; ]
END 过程名;
2)函数:
创建语法
CREATE [OR REPLACE]FUNCTION 函数名 (参数说明1,参数说明2,。。。)
RETURN 类型 IS
[ 局部说明]
BEGIN
执行语句;
RETURN( 返回值);
[EXCEPTION
例外处理; ]
END 函数名;
在例外处理中也要有RETURN语句存在,否则主调语句会报”没有返回值”的错误.
如果是要求返回一个CURSOR,需要先定义
TYPE g_grp_cur is REF CURSOR;
FUNCTION SP_SEARCH()
RETURN g_grp_cur
AS
o_grp_cur g_grp_cur;
BEGIN
OPEN o_grp_cur FOR
(SQL 语句);
RETURN o_grp_cur;
EN D SP_SEARCH;
不论在过程还是函数中均可再套用SQL语句块.
例:
FUNCTION SP_ADD()
RETURN VARCHAR2
AS
BEGIN
…………….
DECLARE
A INTEGER := 0;
BEGIN
NULL;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END;
……………
RETURN ‘AAA’;
END SP_ADD;
CREATE [OR REPLACE]FUNCTION 函数名 (参数说明1,参数说明2,。。。)
RETURN 类型 IS
[ 局部说明]
BEGIN
执行语句;
RETURN( 返回值);
[EXCEPTION
例外处理; ]
END 函数名;
在例外处理中也要有RETURN语句存在,否则主调语句会报”没有返回值”的错误.
如果是要求返回一个CURSOR,需要先定义
TYPE g_grp_cur is REF CURSOR;
FUNCTION SP_SEARCH()
RETURN g_grp_cur
AS
o_grp_cur g_grp_cur;
BEGIN
OPEN o_grp_cur FOR
(SQL 语句);
RETURN o_grp_cur;
EN D SP_SEARCH;
不论在过程还是函数中均可再套用SQL语句块.
例:
FUNCTION SP_ADD()
RETURN VARCHAR2
AS
BEGIN
…………….
DECLARE
A INTEGER := 0;
BEGIN
NULL;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END;
……………
RETURN ‘AAA’;
END SP_ADD;
3)包
是被封装到单独一个单元的一组过程,函数,变量,SQL语句。包定义中声明的变量属于全局变量.只在包体中声明的过程,函数为该包的私有函数.如果包中函数A调用包中函数B,则B必须先于A声明,否则报错.包内过程,函数支持重载, 重载同JAVA.
在包定义中声明的函数必须在包体中实现.
包类似 与C的INCLUDE文件。使用包可以使程序变得模块化且易于管理.
创建语法,分为两个部分
包定义部分
CREATE [OR REPLACE]PACKAGE 包名
{IS|AS}
SQL 语句;
E
在包定义中声明的函数必须在包体中实现.
包类似 与C的INCLUDE文件。使用包可以使程序变得模块化且易于管理.
创建语法,分为两个部分
包定义部分
CREATE [OR REPLACE]PACKAGE 包名
{IS|AS}
SQL 语句;
E