您的位置:首页 > 数据库

PL/SQL基础知识讲解

2018-01-31 23:03 639 查看
为了介绍后文中数据库的基本对象–包,存储过程,存储函数等,这里有必要先对pl/sql基础做一遍了解。

pl/sql简介

全称:procedure language /Struct Query languager;从全程可以读出,这是一门过程化编程语言而且还是一门结构化查询语言。(见名知义),pl/sql是一种高级数据库程序设计语言,该语言专门用在各种环境下对oracle数据库进行访问,同时该语言集成于数据库服务器中,所以pl/sql代码可以对数据进行快速高效的处理。PL/SQL的使用,使SQL成为一种高级程序设计语言,支持高级语言的块操作,条件判断,循环语句,嵌套等.

本篇介绍重点:由于介绍pl/sql基础的目的一是了解pl/sql这门编程语言,二是为了介绍后文的数据库对象做铺垫,所以就简单的介绍一下pl/sql基础了。

pl/sql 理论概述

pl/sql 块结构和组成元素

pl/sql 常用运算符和表达式

pl/sql 游标

pl/sql 异常处理

pl/sql 存储过程、存储函数(会在下一篇单独介绍)

1.概述

之前已经对pl/sql做过简介了,这里在补充两点:

(1) pl/sql是oracle系统的核心语言,现在oracle的许多部件都是用pl/sql写成的。在pl/sql中可以使用的sql语句有:

INSERT,UPDATE,DELETE, SELECT …INTO …COMMIT,ROLLBACK,SAVEPOINT.

(2)pl/sql 的运行是通过oracle中的一个引擎来进行的,这个引擎可能在oracle的服务器端,也可能在oracle应用开发的客户端,引擎执行pl/sql的过程性语句,然后将SQL语句发送给数据库服务器来执行,再将结果返回给执行端。

2.pl/sql块结构和组成元素

(1)pl/sql块

pl/sql程序由三个块组成,即声明部分,执行部分,异常处理部分

所以pl/sql块结构如下所示:

DECLARE

/声明部分:在此声明我们要使用的变量,记录类型,及游标等,还包括局部的存储过程和函数/

BEGIN

/执行部分:过程及SQL语句,及程序的主要部分/

EXCEPTION

/执行异常部分:对我们的错误进行处理/

END;

pl/sql块可以分为三类:

1.无名块:动态构造,只能执行一次;

2.子程序:存储在数据库的存储过程,函数和包等,当在数据库建立好后,可以在其他程序中调用他们;

3.触发器:当数据库发生操作时,会触发一些事件,从而自动执行响应的程序。

(1)标识符:我们在编写pl/sql中会定义很多标识符,这里定义表示符的规则和我们使用sql语言定义标识符的规则是一样的,比如第一个字符必须为字母,不分大小写。这里强调一点就是:一般变量名声明与表中字段完全一样,如果这样可能就得不到正确的结果。

(3)变量命名在pl/sql中还是有特别的讲究,建议按照一个标准命名,如下是建议命名规则



(4)变量类型这里的变量类型和SQL中是一样的,常用char ,varchar2,number,Date.等;

但是这里与SQL存在不同的地方在于,oracle在pl/sql中除了提供像前面介绍的这些类型外,还介绍了一种称为复合类型的类型–记录类型和表。

记录类型:是把逻辑相关的的数据作为一个单元存储起来,称作pl/sql RECORD 的域(field),其作用就是存放互不相同但逻辑相关的信息。

语法格式:

Type name_record IS RECORD(

Field type1 [NOT NULL] [:=exp1], –变量名 变量类型 是否为空 设置初始值 赋值运算符为 “:= ”

Field type2 [NOT NULL] [:=exp2],

… …

Field typen [NOT NULL] [:=exp3]

)

eg:

declare

type emp_record is record(

v_id number(10) not null :=10000,

v_name varchar2(8),

)

v_emp emp_record; //记录类型本身只是一个数据类型,而并非数据对象,所以我们在使用的时候需要声明一个数据对象 ,对象名称 对象类型

begin

v_emp.v_name :=’huangfz’;

dbms_output.put_line(v_emp.v_id||’,’||v_emp.v_name);

end;

–dbms_output.put_line()为输出语句,相当于system.out.println();

使用这个之前需要先执行语句 set serveroutput on;

该题则打印10000,huangfz,

对记录类型的理解就好比我们java中类一样,里面的为成员变量–不严谨的比喻。

(5)%type ,select …into..

declare

v_id employees.employee_id%type,

v_ename employees.last_name%type,

v_sal employees.salary%type

begin

select employee_id ,last_name ,salary into v_id,v_ename,v_sal from employees where employee_id=40;

dbms_output.put_line(v_id||’,’||v_ename||’,’||v_sal);

end;

从以上案例中我们可以学到两个知识点,当我们不知道定义的变量类型为什么时,我们可以引用已经存在的表字段类型,这样该变量的类型就和表字段类型一致定义格式如: 变量名 表名.字段名%type

同时我们也应学会在pl/sql中对通过查询结果对变量赋值采用的是select 表字段 into 变量名 from 表 ;

当然这里面还有一个更厉害的就是rowtype,我们使用type取的只是一个字段的类型,而用它就不一样了,他返回的是整个表的字段类型,所以他返回的是一个记录类型,且数据结构和表的一样如下示例:

declare

v_emp employees%rowtype;

begin

select * into v_emp from employees where employee_id=20

dbms_output.put_line(v_emp.employee_id||’,’||v_emp.last_name||’,’||to_char(v_emp.hiredate,’yyyy-mm–dd’));

end;

在运算符方面除了赋值运算符是 := 其余的运算符都和SQL运算符一样。

3.流程控制

这里只介绍最基本的两种流程控制一个是if判断一个是loop 循环。

(1)IF:

常见格式:

if 布尔表达式 then

pl/sql或sql语句;

end if;

if 布尔表达式 then

pl/sql或sql语句;

else

pl/sql或sql语句;

end;

if 布尔表达式 then

pl/sql或sql语句;

elsif 布尔表达式 then

pl/sql或sql语句;

elsif 布尔表达式

pl/sql或sql语句;

else

pl/sql或sql语句;

end;

拿第三种情况举例(注意是elsif ,不是elseif)

declare

v_eid number(10);

v_sal number(10);

v_content varchar2(20);

begin

select salary into v_sal from emp where employee_id=44;

if v_sal>5000 then

v_content :=’高薪’;

elsif v_sal>3000 then

v_content :=’中薪’;

else

v_content :=’低薪’;

end if;

dbms_out.put_line(‘他的薪资范围属于:’||v_content);

end;

这里顺便提一个 case when then 语句,也是经常用的和if then 没啥区别适合做等值判断,格式如下:

case 变量

when 变量值 then

pl/sql语句

when 变量值 then

pl/sql语句

when 变量值 then

pl/sql语句

else pl/sql语句

end;

eg:如查询成绩如果是A就是优秀,B就是良好,C就是中等,D及格

declare

v_result varchar2(4);

v_grade varchar2(4);

begin

select gresult into v_grade from testEng where tid=101;

v_result :=

case v_grade

when ‘A’ then ‘优秀’

when ‘B’ then ‘良好’

when ‘C’ then ‘中等’

when ‘D’ then ‘及格’

else ‘不及格’

end;

dbms_output.put_line(v_result);

end;

(2)Loop循环:

循环的地位可是非常重要的,我们一般获取多条数据时都是需要通过循环遍历出来的。可分为while循环和for循环

while循环:

loop

要执行的语句

exit while 表达式 (满足条件则退出循环,这里和java里面的刚好相反)

end loop;

while 表达式 loop

执行语句;

end loop; 推荐使用这一种,满足条件执行

eg:打印2-100所有的素数

declare

v_i number(3) :=2;

v_j number(3) :=2;

v_flag number(2) :=1;

begin

while v_i <=100 loop

while v_j <=sqrt(v_i) loop

if mod(v_i,v_j)=0 then v_flage=0; goto label;

end if;

v_j :=v_j+1;

end loop;

<<’label’>> //使用时要把引号去了,这里不加显示不了

if v_flag =1 then dbms_output.put_line(v_i);

v_j := 2;

v_flage :=1;

v_i :=v_i+1;

end loop;

//本题还使用了goto 关键字,实现直接跳转到指定label区运行,因为已经判断他不是素数了,就没必要在继续了,相当于java 中的continue

for循环:

for循环可是一个相当好用的循环,也成为数字循环;

格式如下:

for 计数变量 in [reverse] 下线 .. 上线 loop

执行语句

end loop

//每执行一次,变量自动加一,当使用reverse变量自动减1,跟在in [reverse]的数必须是从小到大,而且必须是整数.可以使用exit退出循环。

同样打印2-100的素数

declare

v_flag :=1;

begin

for v_i in 2 .. 100 loop

for v_j in 2 .. sqrt(v_i) loop

if mod(v_i,v_j) =0 then v_flag =0;

goto label;

end if;

end loop;

<<’label’>> //使用时要把引号去了,这里不加显示不了

if v_flag =1 then dbms_output.put_line(v_j);

end if;

v_flag :=1;

end loop

end;

由于感觉篇幅过长,所以游标就放在下一个篇文章详细介绍了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息