引言
过程化SQL语言(Procedural Language/SQL)是Oracle数据库对SQL语句的扩展:在普通SQL语句的使用上增加了编程语言的特点,把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算的程序语言。
优点:
- 可以对程序中的错误进行自动处理,使程序能够在遇到错误的时候不会被中断;
- 具有较好的可移植性,可以移植到另一个Oracle数据库中;
- 集成在数据库中,调用更快;
- 减少了网络的交互,有助于提高程序性能。
客户端发出调用PL/SQL的执行命令,数据库接收到执行命令后,在数据库内部完成整个PL/SQL程序的执行,并将最终的执行结果反馈给用户。在整个过程中网络里只传输了很少的数据,减少了网络传输占用的时间,所以整体程序的执行性能会有明显的提高。
I 预备知识
- 多行注释
/* */
- 单行注释
--
1.1 PL/SQL程序的基本结构
由四个基本部分组成:块头
、声明单元
、执行单元
、异常处理单元
[HEADER]
[declare]
--定义变量
begin
--过程语句
[exception]
--处理 异常
end;
输出helloworld
begin
dbms_output.put_line('hello');
end;
--如果过程执行完没有输出,必须将服务器输出打开
执行
SQL> set serveroutput on/off;
SQL>
SQL> begin
2 dbms_output.put_line('hello');
3 end;
4 /
1.2 变量
declare
--变量名称 变量类型;
begin
end;
--标识符:不能以数字开始 长度不能超过30个字符
- 变量初始化: 采用
:=
进行赋值
v_age number(10) := 10;
- 变量类型
number(m,n)
数字类型char()
固定长度字符串varchar2()
可变长度字符串date
日期类型boolean(true/false/null)
布尔类型binary_integer
有符号整型
注意:布尔类型不能直接输出
--变量
declare
--声明变量
v_name varchar2(20);
--1v_name varchar2(20); 错误变量名称
--aaaaaaaaaa_aaaaaaaaaa_aaaaaaaa varchar(10);
v_age number(10) := 10;
v_password char(10) := 'aaa';
v_date date := sysdate;
v_flag boolean := null;
v_integer binary_integer := 1;
--常量
c_pi constant number(3,2) := 3.14;
-- 常量声明的时候要初始化
-- c_pi constant number(3,2);
--变量声明为非空类型
v_test varchar2(10) not null := null;
begin
v_age := 20;
dbms_output.put_line(v_age);
dbms_output.put_line(v_password);
dbms_output.put_line(v_date);
dbms_output.put_line(v_integer);
if v_flag then
dbms_output.put_line('true');
else
dbms_output.put_line('false');
end if;
--常量不能赋值
-- c_pi := 3.33;
dbms_output.put_line(c_pi);
end;
- 变量名称: 不能是SQL关键字,最好不要和表中字段同名。
变量命名:v_实际含义的单词
常量命名:c_实际含义
参数命名: p_实际含义
游标类型: 名称_cursor
表类型: 名称_table
记录类型: 名称_record
- 变量作用域: 变量从声明开始到对应模块的end结束为它的作用域
变量作用域代码示例
declare
v_name varchar2(10) := 'name1';
v_age binary_integer := 20;
begin
declare
v_name varchar2(10) := 'name2';
begin
v_age := 10;
dbms_output.put_line(v_age);
dbms_output.put_line(v_name);
end;
dbms_output.put_line(v_name);
dbms_output.put_line(v_age);
end;
II 变量的其他类型
2.1 表类型
表类型类似java中的数组,用来存储具有同种类型的数据。
定义表类型:
type 表类型名称 is table of 表类型存储的基本类型 index by binary_integer
声明变量为表类型: 变量名称 表类型名称
属性:表类型通过下标操作
first
表示获得表类型的第一个下标last
表示获得表类型的最后一个下标count
表示表类型的数据个数next(下标)
表示下一个下标prior(下标)
表示前一个下标
--表类型
declare
--声明一个表类型,名称为table_type
type table_type is table of varchar2(20) index by binary_integer;
v_name table_type;
begin
v_name(0) := 'hello1';
v_name(1) := 'hello2';
v_name(2) := 'hello3';
v_name(3) := 'hello4';
v_name(10) := 'hello10';
--存储其他类型
--v_name(4) := 4;
--v_name(5) := sysdate;
dbms_output.put_line(v_name(0));
--dbms_output.put_line(v_name(4));
--dbms_output.put_line(v_name(5));
--dbms_output.put_line(v_name(5)); 未找到数据
dbms_output.put_line(v_name.first);
dbms_output.put_line(v_name.last);
dbms_output.put_line(v_name.count);
dbms_output.put_line(v_name.next(3));
dbms_output.put_line(v_name.prior(0));
end;
2.2 记录类型
用来存储一条记录
type 记录类型名称 is record(field1 类型,field2 类型)
定义变量,将变量类型设置成记录类型: v_record 记录类型名称
declare
--定义记录类型
type emp_record_type is record(id number(4),name varchar2(10),work varchar2(9) );
--定义变量,变量类型为记录类型
v_emp_record emp_record_type;
begin
--查询语句
select empno,ename,job into v_emp_record.id,v_emp_record.name,v_emp_record.work from emp where empno=7369;
--输出记录字段
dbms_output.put_line(v_emp_record.id);
dbms_output.put_line(v_emp_record.name);
dbms_output.put_line(v_emp_record.work);
end;
2.3 定义表类型的简单方式
表名.字段名%type
declare
--定义表类型,表类型的元素类型 采用emp.ename字段类型
--此时的表类型 类似一个普通变量
v_record emp.ename%type;
begin
select ename into v_record from emp where empno=7369;
select ename into v_record from emp where empno=1;
dbms_output.put_line(v_record);
end;
2.4 定义记录类型的简单方式
定义记录类型 表名%rowtype
declare
--定义记录类型的变量,记录类型仿照emp表中的字段进行 --建立的记录类型就和对应表的字段一一对应
v_record emp%rowtype;
begin select * into v_record from emp where empno=7369; dbms_output.put_line(v_record.empno); dbms_output.put_line(v_record.ename);
dbms_output.put_line(v_record.job);
end;
2.5 将表中的所有记录存在一个变量中
declare
--定义一个表类型
type table_type is table of emp%rowtype index by binary_integer;
v_emp_test table_type;
v_record emp%rowtype;
begin
select * into v_emp_test(0) from emp where empno=7788;
select * into v_emp_test(1) from emp where empno=7369;
select * into v_record from emp where empno=7902;
dbms_output.put_line(v_emp_test(0).ename);
v_emp_test(2) := v_record;
dbms_output.put_line(v_emp_test(2).ename);
end;
III 操作符
3.1 算数运算符
v_age number(3) := 0;
v_age := v_age +1;
--跟java一致
3.2 比较运算符
>
<
>=
=
不等于: !=
` <>
~=
^= `
3.3 逻辑运算符
and
or
not
between and
3.4 赋值运算符
:=