一、PL/SQL简介:
(1)PL/SQL俗称过程化SQL语言(Procedural Language/SQL),是Oracle对SQL的
过程化扩充 而形成的程序开发语言。在普通SQL语句的使用上增加了编程语言的特点,
所以PL/SQL就是把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算的程序语言。
(2)PL/SQL中提供了和其他高级语言类似的块操作,条件判断,循环结构等特性,
将SQL的数据操纵功能与过程化语言的流程控制结构结合起来,能够完善更复杂的业务处理
(3)PL/SQL程序不能在Oracle以外的其他关系型数据库管理系统中运行
◆PL/SQL的特点:
(1)PL/SQL是一种块结构语言,一个PL/SQL程序就是一个块,块中可以嵌套子块,能够使一组SQL语句的功能更具模块化程序特点;
(2)每个块中可以定义变量,变量的作用范围仅限于该块;
(3)PL/SQL程序块中可以使用SQL的查询语句,DML(表的增删改操作)语句及事务处理语句,可以对程序中的错误进行自动处理,使程序能够在遇到错误的时候不会被中断;
(4)PL/SQL程序大小写不敏感
(5)Oracle中的PL/SQL引擎负责解释和执行PL/SQL程序,PL/SQL程序可以直接和SQL引擎进行交互
PL/SQL引擎的作用:编写的SQL语句,通过网络、java程序或者客户端工具发送给关系型数据库管理系统,PL/SQL引擎负责拿到这个字符串(SQL语句就是一个字符串文本格式),对其SQL语句进行语法分析,判断该SQL语句否符合Oracle中的语法要求,若符合,则执行SQL语句.
◆PL/SQL程序块与SQL语言的区别:
(1)SQL语句:通过多条SQL语句实现功能时,每条语句都需要在客户端和服务端传递,而且每条语句的执行结果也需要在网络中进行交互,占用了大量的网络带宽,消耗了大量网络传递的时间,而在网络中传输的那些结果,往往都是中间结果,而不是我们所关心的。
(2)PL/SQL程序块:而使用PL/SQL程序是因为程序代码存储在数据库中,程序的分析和执行完全在数据库内部进行,用户所需要做的就是在客户端发出调用PL/SQL的执行命令,数据库接收到执行命令后,在数据库内部完成整个PL/SQL程序的执行,并将最终的执行结果反馈给用户。在整个过程中网络里只传输了很少的数据,减少了网络传输占用的时间,所以整体程序的执行性能会有明显的提高。
◆PL/SQL块有以下三部分组成:
声明部分(可选):声明常量、变量、复杂数据类型、游标等;
(执行部分(必须):包含若干语句以实现特定功能;
异常处理部分(可选):处理运行错误
◆PL/SQL块结构:
declare
声明部分
begin
执行部分,可包含SQL语句或PL/SQL控制语句
exception
异常处理部分
end;
二、从表中检索单行数据
在PL/SQL中,select语句汇总可使用 into 子句将检索的数据赋值给变量
◆语法格式:
select columnList
into variableNameList
from tableName
where condition
注意:
(1)variableNameList中变量的个数、数据类型必须和columnList匹配
(2)使用select into检索数据,必须保证只能返回一条数据,否则均会抛出错误
【示例】编写PL/SQL程序,查询并输出编号为 2 的产品编号、名称和价格
declare
v_id products.product_id%type; --v_i使用的 %type用于指定products表中的列类型
v_name products.name%type;
v_price products.price%type;
v_count int;
begin
select count(*)
into v_count
from products p
where p.product_id = 2;
if v_count = 0 then
dbms_output.put_line('记录不存在!');
else
select p.product_id,p.name,p.price
into v_id,v_name,v_price
from products p
where p.product_id = 2;
dbms_output.put_line(v_id||','||v_name||','||v_price);
end if;
end;
◆记录类型(Record) --类似于java中的类
在PL/SQL中,可使用记录类型的变量来接收检索的多列数据。每个记录类型变量中包含了多个成员
--要使用记录类型,必须先定义该类型,然后才能定义该类型的变量
◆定义Record类型的语法
type typeName is record (memberDefineList)
注意:
(1)typeName为类型名
(2)memberDefineList是以逗号隔开的成员定义列表
(3)Oracle建议类型名带t_前缀,带_record_type后缀;记录类型变量带_record后缀
(4)select子句中的列名顺序和记录类型中的成员顺序保持一致
◆使用 . 可访问记录类型变量中的成员
【示例】将检索到的数据放入记录类型的变量中,然后输出每个成员的值
--记录类型的变量相互赋值时均为值拷贝
declare
--定义记录类型
type t_prd_record_type is record(m_id products.product_id%type,
m_name products.name%type,
m_price products.price%type);
--定义变量
v_prd_record1 t_prd_record_type;
v_prd_record2 t_prd_record_type;
v_count int;
begin
select count(*)
into v_count
from products p
where p.product_id = 2;
if v_count = 0 then
dbms_output.put_line('记录不存在!');
else
select p.product_id,p.name,p.price
into v_prd_record1
from products p
where p.product_id = 2;
v_prd_record2 := v_prd_record1; --记录类型变量的值拷贝
--修改其记录类型1的各值
v_prd_record1.m_id := 4;
v_prd_record1.m_name := 'prd4';
v_prd_record1.m_price := 23.6;
--输出两个记录类型变量的值
dbms_output.put_line(v_prd_record1.m_id||','||v_prd_record1.m_name||','||v_prd_record1.m_price);
dbms_output.put_line(v_prd_record2.m_id||','||v_prd_record2.m_name||','||v_prd_record2.m_price);
end if;
dbms_output.put_line(v_prd_record2.m_id||','||v_prd_record2.m_name||','||v_prd_record2.m_price);
end;
◆使用%rowtype获取表的行类型
行类型也属于记录类型
如:
v_prd_record products%rowType;
表明v_prd_record变量可以存储产品表中的一行记录
可以直接将一行记录赋值
select * into v_product_record from products where product_id = 3;
使用%rowType定义的记录变量中的成员名称、类型与表中的列完全一致
【示例】PL/SQL中使用行类型来操作表
declare
v_prd_record products%Rowtype;
begin
select *
into v_prd_record
from products p
where p.product_id = 3;
dbms_output.put_line(v_prd_record.product_id||','||v_prd_record.name||','||v_prd_record.price);
end;