复合类型-pl/sql表类型
相当于高级语言中的数组,但是需要注意的是在高级语言中数组的下标不能为负数,而pl/sql是可以为负数的,并且表元素的下标没有限制。实例如下:
Sql代码
.declare
.--定义了一个pl/sql表类型sp_table_type,该类型是用于存放emp.ename%type这种类型的数据,
.--index by binary_integer 表示下标是整数
. type sp_table_type is table of emp.ename%type
. index by binary_integer;
.--定义了一个sp_table变量,这个变量的类型是sp_table_type
. sp_table sp_table_type;
.begin
. select ename into sp_table(-) from emp where empno = ;
. dbms_output.put_line('员工名:' || sp_table(-));
.end;
说明:
sp_table_type 是pl/sql表类型
emp.ename%type 指定了表的元素的类型和长度
sp_table 为pl/sql表变量
sp_table() 则表示下标为0的元素
注意:如果把select ename into sp_table(-) from emp where empno = ;变成select ename into sp_table(-) from emp;则运行时会出现错误,错误如下:
ORA-:实际返回的行数超出请求的行数
解决方法是:使用参照变量(这里不讲)
复合变量——嵌套表(nested table)
复合变量——变长数组(varray)
参照变量
参照变量是指用于存放数值指针的变量。通过使用参照变量,可以使得应用程序共享相同对象,从而降低占用的空间。在编写pl/sql程序时,可以使用游标变量(ref cursor,用的最多)和对象类型变量(ref obj_type)两种参照变量类型。
参照变量——ref cursor游标变量
使用游标时,当定义游标时不需要指定相应的select语句,但是当使用游标时(open时)需要指定select语句,这样一个游标就与一个select语句结合了。实例如下:
.请使用pl/sql编写一个块,可以输入部门号,并显示该部门所有员工姓名和他的工资。
.在1的基础上,如果某个员工的工资低于200元,就添加100元。
Sql代码
.declare
.--定义游标sp_emp_cursor类型
. type sp_emp_cursor is ref cursor;
.--定义一个游标变量
. test_cursor sp_emp_cursor;
.--定义变量
.v_ename emp.ename%type;
.v_sal emp.sal%type;
.begin
.--执行
.--把test_cursor和一个select结合
.open test_cursor for select ename,sal from emp where deptno=&no;
.--循环取出
.loop
. fetch test_cursor into v_ename,v_sal;
. --判断是否test_cursor为空
. exit when test_cursor%notfound;
. dbms_output.put_line('名字:'||v_ename||' 工资:'||v_sal);
.end loop;
.end;
/
pl/sql的进阶--控制结构(分支,循环,控制)
pl/sql的进阶--控制结构
在任何计算机语言(c,java,pascal)都有各种控制语句(条件语句,循环结构,顺序控制结构...)在pl/sql中也存在这样的控制结构。
在本部分学习完成后,希望大家达到:
.使用各种if语句
.使用循环语句
.使用控制语句——goto和null;
条件分支语句
pl/sql中提供了三种条件分支语句if—then,if – then – else,if – then – elsif – then
这里我们可以和java语句进行一个比较
简单的条件判断 if – then
问题:编写一个过程,可以输入一个雇员名,如果该雇员的工资低于2000,就给该员工工资增加10%。
Sql代码
.create or replace procedure sp_pro6(spName varchar2) is
.--定义
.v_sal emp.sal%type;
.begin
. --执行
. select sal into v_sal from emp where ename=spName;
. --判断
. if v_sal< then
. update emp set sal=sal+sal*% where ename=spName;
. end if;
.end;
./
二重条件分支 if – then – else
问题:编写一个过程,可以输入一个雇员名,如果该雇员的补助不是0就在原来的基础上增加100;如果补助为0就把补助设为200;
Sql代码
.create or replace procedure sp_pro6(spName varchar2) is
.--定义
.v_comm emp.comm%type;
.begin
. --执行
. select comm into v_comm from emp where ename=spName;
. --判断
. if v_comm<> then
. update emp set comm=comm+ where ename=spName;
. else
. update emp set comm=comm+ where ename=spName;
. end if;
.end;
./
多重条件分支 if – then – elsif – then
问题:编写一个过程,可以输入一个雇员编号,如果该雇员的职位是PRESIDENT就给他的工资增加1000,如果该雇员的职位是MANAGER就给他的工资增加500,其它职位的雇员工资增加200。
Sql代码
.create or replace procedure sp_pro6(spNo number) is
. --定义
. v_job emp.job%type;
.begin
. --执行
. select job into v_job from emp where empno=spNo;
. if v_job='PRESIDENT' then
. update emp set sal=sal+ where empno=spNo;
. elsif v_job='MANAGER' then
. update emp set sal=sal+ where empno=spNo;
. else
. update emp set sal=sal+ where empno=spNo;
. end if;
.end;
./
循环语句 –loop
是pl/sql中最简单的循环语句,这种循环语句以loop开头,以end loop结尾,这种循环至少会被执行一次。
案例:现有一张表users,表结构如下:
用户id | 用户名
|
请编写一个过程,可以输入用户名,并循环添加10个用户到users表中,用户编号从1开始增加。
Sql代码
.create or replace procedure sp_pro6(spName varchar2) is
.--定义 :=表示赋值
. v_num number:=;
.begin
. loop
. insert into users values(v_num,spName);
. --判断是否要退出循环
. exit when v_num=;
. --自增
. v_num:=v_num+;
. end loop;
.end;
/
循环语句 –while循环
基本循环至少要执行循环体一次,而对于while循环来说,只有条件为true时,才会执行循环体语句,while循环以while...loop开始,以end loop结束。
案例:现有一张表users,表结构如下:
用户id 用户名
问题:请编写一个过程,可以输入用户名,并循环添加10个用户到users表中,用户编号从11开始增加。
Sql代码
.create or replace procedure sp_pro6(spName varchar2) is
.--定义 :=表示赋值
. v_num number:=;
.begin
. while v_num<= loop
. --执行
. insert into users values(v_num,spName);
. v_num:=v_num+;
. end loop;
.end;
./
循环语句 –for循环
基本for循环的基本结构如下
Sql代码
.begin
. for i in reverse .. loop
. insert into users values (i, 'shunping');
. end loop;
.end;
我们可以看到控制变量i,在隐含中就在不停地增加。
顺序控制语句 –goto,null
.goto语句
goto语句用于跳转到特定符号去执行语句。注意由于使用goto语句会增加程序的复杂性,并使得应用程序可读性变差,所以在做一般应用开发时,建议大家不要使用goto语句。
基本语法如下 goto lable,其中lable是已经定义好的标号名,
Sql代码
.declare
. i int := ;
.begin
. loop
. dbms_output.put_line('输出i=' || i);
. if i = {} then
. goto end_loop;
. end if;
. i := i + ;
. end loop;
. <<end_loop>>
. dbms_output.put_line('循环结束');
.end;
.null
null语句不会执行任何操作,并且会直接将控制传递到下一条语句。使用null语句的主要好处是可以提高pl/sql的可读性。
Sql代码
.declare
. v_sal emp.sal%type;
. v_ename emp.ename%type;
.begin
. select ename, sal into v_ename, v_sal from emp where empno = &no;
. if v_sal < then
. update emp set comm = sal * 0.1 where ename = v_ename;
. else
. null;
. end if;
end;