Oracle11g学习-PL/SQL

Oracle

1 PL/SQL

pl/sql:块结构语言,是sql(Structured Query Language)语言的一种扩展,结合了oracle过程语言(procedural language)进行使用。

pl/sql块由三部分构成:声明部分、执行部分、异常部分

PL/SQL结构

[DECLARE]

    --声明变量等;

BEGIN

    --程序主要部分,一般用来执行过程语句或SQL语句;

[EXCEPTION]

    --异常处理;

END;

1.1  运算符

等于

 比较运算符

<>,!=,~=,^=

不等于

小于

大于

<=

小于或等于

>=

大于或等于

 +

加号

 算术运算符

 -

减号

 *

乘号

 /

除号

:=

赋值号

赋值运算符

=>

关系号

关系号

..

范围运算符

范围运算符

||

字符连接符

连接运算符

is null

是空值

 逻辑运算符

between and

介于两者之间

in

在一系列值中间

and

逻辑与

or

逻辑或

not

取反

1.2  变量与常量

数据类型

常用标准类型:CHAR(CHARATER,NCHAR),VARCHAR2,NUMBER(P,S),DATE,BOOLEAN等。

属性类型:%TYPE 与 %ROWTYPE

%TYPE:可以用来定义数据变量的类型与已定义的数据变量(表中的列)一致。

%ROWTYPE:与某一数据库表的结构一致(修改数据库表结构,可以实时保持一致);访问方式声明为rowtype的 变量名.字段名。

1.2.1  基本类型

声明

【变量声明】

<变量名> 类型[:=初始值];

【示例】

name varchar2(20) := 'itcast';

【常量声明】

<变量名> CONSTANT 类型:=初始值;

【示例】

pi constant number(5,3):=3.14;

运用

/*定义常量或变量、赋值使用示例*/

DECLARE

     p_empno constant number(4):=7369;

     p_ename varchar2(10);

     p_sal number(7,2);

     p_comm number(7,2);

BEGIN

--赋值方式一:使用select into给变量赋值

select ename,sal into p_ename,p_sal from emp where empno =p_empno;

 

--赋值方式二:使用赋值操作符“:=”给变量赋值

     p_comm:=500;

 

--输出相关信息,DBMS_OUTPUT.PUT_LINE为具有输出功能的函数

     dbms_output.put_line('员工号:'|| p_empno||',姓名:'|| p_ename||',工资:'|| p_sal||',奖金:'|| p_comm);

END;

【注意】

dbms_output是oracle提供的输出对象

put_line是其一个方法,用于输出一个字符串

new_line是其一个方法,用于输出新的一行(换行)

1.2.2  %type类型

声明

【声明】

变量名称 表名.字段%type;

【示例:】

--表示变量name的类型和emp.ename的类型相同

name emp.ename%type;

 运用

/*定义常量或变量、赋值使用示例*/

DECLARE

     p_empno constantnumber(4):=7369;

     p_ename emp.ename%type;

     p_sal emp.sal%type;

     p_comm emp.comm%type;

BEGIN

--赋值方式一:使用select into给变量赋值

select ename,sal into p_ename,p_sal from emp where empno = p_empno;

 

--赋值方式二:使用赋值操作符“:=”给变量赋值

     p_comm:=500;

 

--输出相关信息,DBMS_OUTPUT.PUT_LINE为具有输出功能的函数

     dbms_output.put_line('员工号:'|| p_empno||',姓名:'|| p_ename||',工资:'|| p_sal||',奖金:'|| p_comm);

END;

1.2.3  %rowtype类型

声明

【声明】

变量名称 表%rowtype;

【示例:】

--表示变量test的类型为emp表的行类型;也有 .empno; .ename; .sal ;等属性

test emp%rowtype;

 运用

/*定义常量或变量、赋值使用示例*/

DECLARE

     p_empno constantnumber(4):=7369;

     emp_info emp%rowtype;

     p_comm emp.comm%type;

BEGIN

--赋值方式一:使用select into给变量赋值

select*into emp_info from emp where empno = p_empno;

 

--赋值方式二:使用赋值操作符“:=”给变量赋值

     p_comm:=500;

 

--输出相关信息,DBMS_OUTPUT.PUT_LINE为具有输出功能的函数

     dbms_output.put_line('员工号:'|| p_empno||',姓名:'|| emp_info.ename ||',工资:'|| emp_info.sal ||',奖金:'|| p_comm);

END;

1.3    控制语句
1.3.1  条件语句

【语法】

IF <条件1> THEN

    语句

[ELSIF <条件2> THEN

   语句]

          .

          .

          .

[ELSIF <条件n> THEN

   语句]

[ELSE

    语句]

END IF;

 【示例】

/*

根据员工的工资判断其工资等级(工资大于等于5000为A级,工资大于等于4000为B级,工资大于等于3000为C级,工资大于等于2000为D级,其它为E级)

*/

DECLARE

     p_empno number(4):=7566;

     p_sal emp.sal%type;

BEGIN

--用变量代替条件语句中的真值

select sal into p_sal from emp where empno = p_empno;

 

IF p_sal >=5000THEN

        dbms_output.put_line('员工号为:'|| p_empno ||'的员工的工资级别为:A级');

ELSIF p_sal >=4000THEN

        dbms_output.put_line('员工号为:'|| p_empno ||'的员工的工资级别为:B级');

ELSIF p_sal >=3000THEN

        dbms_output.put_line('员工号为:'|| p_empno ||'的员工的工资级别为:C级');

ELSIF p_sal >=2000THEN

        dbms_output.put_line('员工号为:'|| p_empno ||'的员工的工资级别为:D级');

ELSE

        dbms_output.put_line('员工号为:'|| p_empno ||'的员工的工资级别为:E级');

END IF;

END;

1.3.2 循环语句
1、LOOP

LOOP

   语句;

   EXIT WHEN <条件>

END LOOP;

 【示例】

/*

计算1-10的总和

*/

DECLARE

     p_sum number(4):=0;

     p_num number(2):=1;

BEGIN

LOOP

     p_sum := p_sum + p_num;

     p_num := p_num +1;

EXITWHEN p_num >10;

END LOOP;

     dbms_output.put_line('1-10的总和为:'|| p_sum);

END;

2、WHILE LOOP

WHILE <条件>

LOOP

   语句;

END LOOP;

【示例】

/*

计算1-10的总和

*/

DECLARE

     p_sum number(4):=0;

     p_num number(2):=1;

BEGIN

WHILE p_num <=10

LOOP

     p_sum := p_sum + p_num;

     p_num := p_num +1;

ENDLOOP;

     dbms_output.put_line('1-10的总和为:'|| p_sum);

END;

3、FOR

FOR <循环变量> IN[REVERSE] 下限..上限

LOOP

   语句;

END LOOP;

【说明】..两点表示范围,1..4表示时将从1到4进行循环,起始(例如 1)写前边,REVERSE表示反转,循环时变成从4到1进行。

【示例】

/*

计算1-10的总和

*/

DECLARE

     p_sum number(4):=0;

     p_num number(2):=1;

BEGIN

FOR p_num IN 1..10

LOOP

     p_sum := p_sum + p_num;

ENDLOOP;

     dbms_output.put_line('1-10的总和为:'|| p_sum);

END;

1.3.3  顺序语句

        指定顺序执行的语句;主要包括 null语句。null语句:是一个可执行语句,相当于一个占位符或不执行操作的空语句。主要用来提高程序语句的完整性和程序的可读性。

 /*

输出1-10的数字但跳过数字4

*/

DECLARE

     flag number(2):=0;

BEGIN

WHILE flag <10

LOOP

     flag := flag +1;

if flag =4then

null;-- 占位,不能去掉

else

        dbms_output.put_line(flag);

endif;

ENDLOOP;

END;

1.4  异常处理
1.4.1  异常语法

EXCEPTION

   WHEN <异常类型> THEN

            语句;

   WHEN OTHERS THEN

            语句;

常配套使用的函数:

    SQLCODE函数:返回错误代码,

    SQLERRM函数:返回错误信息

例如输出异常信息: DBMS_OUTPUT.PUT_LINE('其它异常,代码号:'||SQLCODE||',异常描述:'||SQLERRM);

1.4.2  预定义异常

预定义异常指PL/SQL 程序违反 Oracle 规则或超越系统限制时隐式引发(由oracle自动引发)。

常见的预定义异常

CURSOR_ALREADY_OPEN 试图"OPEN"一个已经打开的游标

DUP_VAL_ON_INDEX 试图向有"UNIQUE"中插入重复的值

INVALID_CURSOR 试图对以关闭的游标进行操作

INVALID_NUMBER 在SQL语句中将字符转换成数字失败

LOGIN_DENIED 使用无效用户登陆

NO_DATA_FOUND 没有找到数据时

NOT_LOGIN_ON 没有登陆Oracle就发出命令时

PROGRAM_ERROR PL/SQL存在诸如某个函数没有"RETURN"语句等内部问题

STORAGE_ERROR PL/SQL耗尽内存或内存严重不足

TIMEOUT_ON_RESOURCE Oracle等待资源期间发生超时

TOO_MANY_ROWS "SELECT INTO"返回多行时

VALUE_ERROR 当出现赋值错误

ZERO_DIVIDE 除数为零

【示例】

/*

预定义异常捕获并处理

*/

DECLARE

     p_result number(2);

BEGIN

     p_result :=1/0;

     dbms_output.put_line('没有异常!');

EXCEPTION

WHEN ZERO_DIVIDE THEN

         dbms_output.put_line('除数不能为0!代码为:'||sqlcode||',异常信息为:'||sqlerrm);

WHEN OTHERS THEN

         dbms_output.put_line('其它异常!代码为:'||sqlcode||',异常信息为:'||sqlerrm);

END;

1.4.3  自定义异常

自定义异常:程序在运行过程中,根据业务等情况,认为非正常情况,可以自定义异常。对于这种异常,主要分三步来处理:

1、定义相关异常;在声明部分定义相关异常,

格式:<自定义异常名称> EXCEPTION;

2、抛出异常;在出现异常部分抛出异常,

格式:RAISE <异常名称>;

3、处理异常;在异常处理部分对异常进行处理,

格式:when <自定义异常名称> then ...,

处理异常也可以使用RAISE_APPLICATION_ERROR(ERROR_NUMBER,ERROR_MESSAGE)存储过程进行处理,

其中参数ERROR_NUMBER取值为-20999~-20000的负整数,参数ERROR_MESSAGE为异常文本消息。

【示例】

/*

判断emp中相应empno对应用户的奖金是否低于500,如果低于则抛出并处理自定义异常

*/

declare

     p_comm emp.comm%type;

--自定义异常,名称为comm_exception

     comm_exception EXCEPTION;

BEGIN

Select nvl(comm,0)into p_comm from emp where empno=7499;

--nvl(comm,0)如果comm为null就填充0

if p_comm >=500then

      dbms_output.put_line('奖金大于等于500。');

else

RAISE comm_exception;

End if;

EXCEPTION

WHEN comm_exception THEN

         RAISE_APPLICATION_ERROR(-20001,'奖金低于500,太少了!');

--dbms_output.put_line('奖金低于500!');

WHEN OTHERS THEN

         dbms_output.put_line('其它异常!代码为:'||sqlcode||',异常信息为:'||sqlerrm);

END;

猜你喜欢

转载自blog.csdn.net/chenzuyibao/article/details/80538607