第3章 包
/**创建包规范**/
create package emp_pkg is
procedure update_sal(name varchar2,newsal number);
function income(name varchar2) return number;
end;
/**创建包体**/
create package body emp_pkg is
procedure update_sal(name varchar2,newsal number)
is
begin
update emp set sal=newsal where lower(ename)=lower(name);
end;
function income(name varchar2) return number
is
salary number(7,2);
begin
select sal*12+nvl(comm,0) into salary from emp where lower(ename)=lower(name);
return salary;
end;
end;
select * from emp where lower(ename)='scott';
/***调用存储和函数******/
call emp_pkg.update_sal('scott',1500);
SQL> var income number
SQL> call emp_pkg.income('scott') into :income;
调用完成。
SQL> print income;
INCOME
----------
36000
/************创建触发器**************/
下面的触发器在更新表tb_emp之前触发,目的是不允许在周二修改表:
SQL> create trigger update_dept before insert or update or delete
2 on dept
3 begin
4 if (to_char(sysdate,'dy')='星期二') then
5 raise_application_error(-20600,'不能在周二修改dept',true);
6 end if;
7 end;
8 /
触发器已创建
SQL> insert into dept(deptno,dname) values (90,'luowj');
insert into dept(deptno,dname) values (90,'luowj')
*
第 1 行出现错误:
ORA-20600: 不能在周二修改dept
ORA-06512: 在 "SCOTT.UPDATE_DEPT", line 3
ORA-04088: 触发器 'SCOTT.UPDATE_DEPT' 执行过程中出错
SQL> show errors;
没有错误。
/************%type用法和作用***************/
declare
v_ename varchar2(5);
v_sal number(6,2);
c_tax_rate constant number(3,2):=0.03;
v_tax_sal number(6,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);
dbms_output.put_line('雇员工资:'||v_sal);
dbms_output.put_line('所得税:'||v_tax_Sal);
end;
select * from emp where empno='7788';
/**varchar2把所有字符都占两字节处理(一般情况下)**/
select * from emp where empno='7744';如是填no值的时候是7844,就会报字符串缓冲区太小,原因ename列
最大长度为10字节,只能存储5个字符
下面是用%Type属性 解决如上的问题
/* 当使用%Type属性定义变量时,它会按照数据库列或其他变量来确定新变量的类型和长度*/
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
c_tax_rate constant number(3,2):=0.03;
v_tax_sal v_sal%type;
begin
select ename,sal into v_ename,v_sal from emp where empno=&eno;
v_tax_sal:=v_sal*c_tax_rate;
dbms_output.put_line('雇员名:'||v_ename);
dbms_output.put_line('雇员工资:'||v_sal);
dbms_output.put_line('所得税:'||v_tax_sal);
end;