Oracle的进阶
Oracle进阶:程序包:包是一组相关过程、函数、变量、常量、类型和游标等PL/SQL程序设计元素的组合。 包具有面向对象设计的特点,是对这些PL/SQL程序设计元素的封装。 包: 包头(定义一个包)、包体(定义一个实现包)。 包的相关注意: 1、包和包体必须有相同的名字; 2、包的开始没有begin语句,与存储过程和函数不同 3、在包头部分定义函数和过程的名称和参数,具体实现在包体中定义 4、在包体内声明常量、变量、类型定义、异常、游标时不使用declare 5、包体内的过程和函数的定义不要create or replace语句; 6、包定义和包体是分离开来的 --程序包 --作用:就是用于将常量,变量,过程,函数组合成一个整体,方便归类调用 /* --定义包 create [or replace] package <包名> as|is --定义变量 --定义常量 --定义类型 --定义过程(是没有实现的) --定义函数(是没有实现的) end [<包名>]; --实现包 create or replace package body <包名> as --实现定义包的函数 --实现定义的的过程 end [<包名>]; 注意事项: 1.有定义包可以不用实现包,但如果有实现包一定对应一个定义包。 2.实现的包名与定义的包名要一样的 3.包里面定义的变量,常量,过程,函数调用格式为 包名.过程 包名.函数 包名.变量 包名.常量 */ --查看程序包 select * from user_objects where OBJECT_TYPE='PACKAGE'; --创建一个定义包 create or replace package pack1 as v_say_hello varchar2(20):='Hello World!'; --定义的存储过程是不需要create or replace procedure pro_say_hello; end; / --创建一个实现包 create or replace package body pack1 as procedure pro_say_hello as begin SYS.dbms_output.put_line(pack1.v_say_hello); end pro_say_hello; --end后面的过程可以忽略不写 end pack1; / --调用包里面的存储过程 set serveroutput on; exec pack1.pro_say_hello; --删除包 --删除实现包 drop package body pack1; --删除定义包 drop package pack1; --应用 /* 创建一个包含有变量、存储过程和函数的包;其中 存储过程可根据员工号查询并输出员工的姓名和工资 函数中利用定义的变量,然后则根据员工号查询出该员工奖金并返回 */ --创建一个定义包 create or replace package pack2 as --定义一个员工的编号 v_empno emp.empno%type:=7788; --定义了一个过程 procedure pro_find_emp_by_empno(p_empno in emp.empno%type,p_emp out emp%rowtype ); --定义一个函数 function fn_find_com_by_empno(p_empno in emp.empno%type) return emp.comm%type; end; / create or replace package body pack2 as --实现过程 procedure pro_find_emp_by_empno(p_empno in emp.empno%type,p_emp out emp%rowtype ) as begin select * into p_emp from emp where empno=p_empno ; end pro_find_emp_by_empno; --实现函数 function fn_find_com_by_empno(p_empno in emp.empno%type) return emp.comm%type as v_comm emp.comm%type; begin select comm into v_comm from emp where empno=p_empno; return v_comm; end fn_find_com_by_empno; end; --调用过程 declare v_emp emp%rowtype; begin pack2.pro_find_emp_by_empno(7788,v_emp); SYS.dbms_output.put_line(v_emp.ename||'--'||v_emp.sal); end; --调用方法 declare v_comm emp.comm%type; begin v_comm:= pack2.fn_find_com_by_empno(pack2.v_empno); SYS.dbms_output.put_line(v_comm); end; 触发器:触发器常用于在sql生效前或者后触发出特定的功能。常用于和序列实现数据插入时自增长的效果。 --触发器 --就是在操作(增,删,改)记录的时候,触发其它的数据行为(增删查改...); /* 语法 create or replace trigger <名字> after|before --两选一,表示在操作之前触发,还是在操作之后触发。 inser|update|delete [of <字段名>] on <表名> --触发的情况,三选1,update,insert,delete [for each row] --plsql语句 [delcare] --定义 begin end; after|before: --两选一,表示在操作之前触发,还是在操作之后触发。 inser|update|delete --触发的情况,三选1,update,delete [of <字段名>]:指定触发的字段,update触发器使用 on <表名> 触发器对应名 [for each row]:如果设置了就是行级触发器,不设置就是表级触发器 行级触发器:每影响一行记录就触一次 表级触发器:不管影响多少行记录,每次只触一次。 plsql:用于编写触发的行为 */ --需求:员工表插入数据的时候,打印HelloWorld create or replace trigger tri_insert_emp after insert on emp for each row begin sys.dbms_output.put_line('HelloWorld!'); end; --查看触发器 select * from sys.user_triggers; --插入一个员工 insert into emp(empno,ename,sal) values(44,'tri1',1000); --停用指定触发器 alter trigger tri_insert_emp disable; --启用指定触发器 alter trigger tri_insert_emp enable; --如果一个表有多个触发器,如何一次停止该表所有触发器 alter table emp disable all triggers; --启动同一个表所以的触发器 alter table emp enable all triggers; --删除触发器 drop trigger tri_insert_emp; -- /* 触发器使用:删除表的同时备份表数据到另一张备份表 */ create table emp_bak as select * from emp where 1=2; --表级触发器:不管任何的行数是多少,每次只触发一次触发器 create or replace trigger tri_emp_delete before delete on emp begin insert into emp_bak select * from emp; end; delete from emp;
|