包
包用于在逻辑上组合过程和函数,它由包规范和包体两部分组成。
我们可以使用create package命令来创建包
create package morf_package isprocedure update_sal(name varchar2,newSal number);function annual_income(name varchar2) return number;end;
包的规范只包含了过程和函数的说明,但是没有过程和函数的实现代码。包体用于实现包规范中的过程和函数。
建立包体可以使用create package body命令。
create or replace package body morf_package isprocedure update_sal(name varchar2,newSal number) isbeginupdate emp set sal=newSal where ename=name;end;function annual_income(name varchar2) return number isannual_salary number;beginselect sal*12+nvl(comm.,0) into annual_salary from emp where ename=name;return annual_salary;end;end;
如何调用包的过程或是函数
当调用包的过程或是函数时,在过程和函数前需要带有包名,如果要访问其他方案的包,还需要在包名前加方案名。
如:
call morf_package.update_sal(‘SCOTT’,9999);
特别说明, 包是pl/sql中非常重要的部分,我们在使用过程分页时,将会再次体会它的威力,呵呵……
触发器
触发器是指隐含的执行的存储过程,当定义触发器时,必须要指定触发的事件和触发的操作。常用的触发事件包括insert,update,delete语句,而触发操作实际就是一个pl/sql块,可以使用create trigger来建立触发器。它很有用,可以维护数据库的安全和一致性。后面再详细介绍。
在编写pl/sql时,可以定义变量和常量,在pl/sql程序中包括有:
a. 标量类型(scalar)
b. 复合类型(composite)
c. 参照类型(reference)
d. lob(large object)
下面举几个例子
a. 定义一个变长字符串
v_ename varchar2(9);
b. 定义一个小数
v_sal number(6,2);
c. 定义一个小数并给一个初始值,:=是pl/sql的赋值号
v_sal2 number(6,2):=5.4;
d. 定义一个日期类型的数据
v_hiredate date;
e. 定义一个布尔变量,不能为空,初始值为FALSE
v_valid Boolean not null default false;
--标量的使用declare --定义了一个常量而且有初始值c_tax_rate number(3,2):=0.03;--定义了三个变量v_ename varchar2(10);v_sal number(7,2);v_tax_sal number(7,2);begin--执行部分select ename,sal into v_ename,v_sal from emp where empno=&no;--计算所得税v_tax_sal:=v_sal*c_tax_rate;--打印输出dbms_output.put_line('姓名:'||v_ename||' 工资:'||v_sal||' 所得税:'||v_tax_sal);end;
使用%type类型定义标量
对于上面的pl/sql块有一个问题,就是如果员工的姓名超过5个字符的话,就会有错误,为了降低pl/sql的程序维护量,可以使用%type类型定义变量,这样它会按照数据库列来确定你定义的变量的类型和长度。
使用方法:标识符名 表明.列名%type;
比如v_ename的定义就可以写作:v_ename emp.ename%type;这样就不会出现缓冲区太小的错误了。
复合变量
pl/sql记录、pl/sql表、嵌套表、varray
pl/sql记录
类似于高级语言的结构体
需要注意的是,当引用pl/sql记录成员时,必须要加记录变量作为前缀(记录变量.记录成员)如下:
declare--先定义一个记录类型emp_record_type,--该类型包含三个数据,name,salary,titletype emp_record_type is record(name emp.ename%type,salary emp.sal%type,title emp.job%type);--定义了一个变量morf_record,其类型是emp_record_typemorf_record emp_record_type;beginselect ename,sal,job into morf_record from emp where empno=7788;dbms_output.put_line(‘员工名:’||morf_record.name);end;
pl/sql表
相当于高级语言的数组,但是需要注意的是在高级语言中数组的下标不能为负数,而pl/sql是可以为负数的,并且表元素的下标没有限制,实例如下:
declaretype morf_table_type is table of emp.ename%type index by binary_integer;morf_table morf_table_type;beginselect ename into morf_table(0) from emp where empno=7788;dbms_output.put_line(‘员工名:’|| morf_table(0));end;
说明:
morf_table_type是pl/sql表类型
emp.ename%type指定了表的元素的类型和长度
morf_table为pl/sql表变量
morf_table(0)表示下标为0的原素。
参照变量
参照变量是指用于存放数值指针的变量。通过使用参照变量,可以使得应用程序共享相同对象,从而降低占用的空间。在编写PL/SQL程序时,可以使用游标变量(ref cursor)和对象类型变量(ref obj_type)两种参照变量类型。
--游标的使用declare--声明一个游标类型name_cursor_typetype name_cursor_type is ref cursor;--定义一个游标变量name_cursorname_cursor name_cursor_type;v_ename emp.ename%type;v_sal emp.sal%type;begin--打开游标open name_cursor for select ename,sal from emp where deptno=&no;loop--循环取出内容fetch name_cursor into v_ename,v_sal;--判断游标是否为空exit when name_cursor%notfound;dbms_output.put_line('姓名:'||v_ename||'工资:'||v_sal);end loop;end;