一、pl/sql的概念
pl/sql简单的说就是:sql语句+编程语言的特性。
二、pl/sql的优点
1、可以提高程序的运行效率,因为能够减少数据库的访问次数。
2、可以对复杂的业务逻辑进行封装
3、pl/sql具有编程语言的特性,可以写ifelse实现复杂的业务逻辑
三、pl/sql块
pl/sql是用块来管理内部程序,pl/sql 块分匿名块与命名块。
匿名块:没有名字的就是匿名块,匿名块不会保存到数据库中,执行完就没有了,类似于java中的main方法。
命名块:有名字的块就是命名块。命名块 :过程,函数,游标,触发器
四、pl/sql变量类型
基本类型:
类型名 | 说明 |
varchar | 定长字符串 |
varchar2 | 变长字符串 |
number(n,m) | 数字类型 |
date | 日期类型 |
timestamp | 时间戳类型 |
引入类型
1、%type类型(列类型)
%type类型指的是声明变量的时候,该变量参考某个表的某个列的类型。
例子:
1 declare 2 -- 变量声明部分 v_ename 类型参考emp表的ename的类型 3 v_ename emp.ename%type; 4 v_sal emp.sal%type; 5 begin-- 业务逻辑执行部分 6 select ename,sal into v_ename,v_sal from emp where empno=&请输入员工编号; 7 -- 把员工姓名打印到控制台 8 dbms_output.put_line('员工姓名:'||v_ename||',基本工资:'||v_sal); 9 exception 10 -- 异常处理部分 11 when no_data_found then 12 dbms_output.put_line('您输入的员工编号不存在'); 13 end;
2、%rowtype(行类型)
%rowtype参数某个表的类型。%rowtype中可以存储多个数据,具体可存多少个和表的字段数一样。
例子:
1 declare 2 -- 声明行类型变量 3 v_emp emp%rowtype; 4 begin 5 -- 业务逻辑执行部分 6 select * into v_emp from emp where empno=&请输入员工编号; 7 -- 把员工姓名打印到控制台 8 dbms_output.put_line('员工姓名:'||v_emp.ename||',基本工资:'||v_emp.sal||',奖金:'||v_emp.comm 9 ||'雇佣日期:'||v_emp.hiredate); 10 exception 11 -- 异常处理部分 12 when no_data_found then 13 dbms_output.put_line('您输入的员工编号不存在'); 14 end;
3、record类型(记录类型)
record可以理解为可自定义的行类型,record类型在使用之前必须声明该类型。
例子:
1 declare 2 -- 声明record类型 3 type emp_record_type is record( 4 ename emp.ename%type, 5 sal emp.sal%type, 6 total emp.sal%type); 7 -- 声明record类型的变量 8 v_emp emp_record_type; 9 begin 10 -- 查询数据,给变量赋值 11 select ename,sal,sal+nvl(comm,0) into v_emp from emp where empno=&no; 12 -- 输入record类型变量中的数据 13 dbms_output.put_line('员工姓名:'||v_emp.ename||',基本工资:'||v_emp.sal||',总工资:'||v_emp.total); 14 end;
4、table类型(表类型)
无论是行类型还是记录类型只能存储一行数据,如果要存储多行数据,需要用到table类型。table类型也需要先声明类型,在声明该类型的变量。
例子:
1 根据员工编号查询员工的信息,存储到table类型的变量中,再输出出来。 2 3 declare 4 -- 声明table类型 is table of 后可以跟行类型,也可以是记录类型 5 type emp_table_type is table of emp%rowtype 6 -- 指定下标的增长方式为整数,每次增长index by binary_integer; 7 -- 声明table类型的变量 8 v_emp emp_table_type; 9 begin 10 -- 把编号为7369的员工的信息存储到table类型变量中 11 select * into v_emp(1) from emp where empno=7369; 12 -- 把编号为7499的员工的信息存储到table类型变量中 13 select * into v_emp(2) from emp where empno=7499; 14 --数据table类型变量中的数据 15 dbms_output.put_line('员工姓名:'||v_emp(1).ename||',基本工资:'||v_emp(1).sal); 16 dbms_output.put_line('员工姓名:'||v_emp(2).ename||',基本工资:'||v_emp(2).sal); 17 end;
附:表类型后边可以跟记录类型,如下:
查询员工的姓名,编号,部门名称。(因为部门名称与员工信息并不在同一个表中,所以声明table类型的时候后边需要跟一个记录类型。)
1 declare 2 -- 声明一个record类型,用来存储员工的姓名,编号和部门名称 3 type emp_record_type is record( 4 ename emp.ename%type, 5 empno emp.empno%type, 6 dname dept.dname%type 7 ); 8 -- table类型的变量,is table of 后可以跟行类型,也可以是记录类型 9 type emp_table_type is table of emp_record_type 10 -- 指定下标的增长方式为整数,每次增长1 11 index by binary_integer; 12 -- 声明table类型的变量 13 v_emp emp_table_type; 14 15 begin 16 -- 查找数据 17 select e.ename,e.empno,d.dname bulk collect into v_emp from emp e inner join dept d on d.deptno=e.deptno; 18 -- 循环输出 19 for v_i in v_emp.first..v_emp.last 20 loop 21 dbms_output.put_line('员工编号:'||v_emp(v_i).empno||'员工姓名:'||v_emp(v_i).ename||'部门姓名:'||v_emp(v_i).dname); 22 end loop; 23 24 end;
引入数据类型总结:
返回值为单列可以用%type类型,如果为单行,用%rowtyp和table都可以,只不过,%rowtype的行是自定义的,table的行是参照数据的行的,如果,返回值为多行,用table类型比较合适,如果,返回值为多行,同时列还是自定义的,则用table类型结合%rowtype类型。