第一部分:管理
一、安装oracle
二、卸载
1、停止oracle所有的服务
2、运行oracle Universal Installer卸载oracle
3、修改注册表,删除所有关于oracle的信息
开始-运行-regedit
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Oracle开头的内容删除
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\Oracle开头的内容删除
4、删除oracle系统目录C:\Program Files\Oracle
5、删除各种快捷方式(开始菜单,环境变量)
6 、(重启系统)删除oraclede的工作目录
三、软件版本
8i(Internet)
9i
10g(Grid)
11g
四、
Oracle------甲骨文
DB2---------IBM
MySQL-------SUN(甲骨文)---开源
SQL Server--Microsoft
Oracle:神谕
sqlplus
启动sqlplus
1、通过命令行
cmd-sqlplus-username-password
system/orcl
2、通过集成工具
3、通过浏览器
启动iSQLPlus的服务
地址:http://计算机名:5560/isqlplus
访问问题:
sql server
mysql
oracle
只有一个全局数据库
所有的表都在同一个数据库中
用户隔离
主机字符串
实例:一组内存和进程
一个实例对应着一个数据库
数据库:由一组数据文件,日志文件,控制文件
使用对象:
DBA(数据库管理员,经验)
数据库的安装,配置
用户的创建
权限的分配
数据库的备份,恢复
数据库参数的调整和数据库的优化
对数据库使用的总体规划
程序员(应用角度)
表
视图
触发器
存储过程
函数
序列
同义词
SQL语句
五、SQL PLUS的使用
1、命令使用分号结尾
2、edit;编辑缓存区中存放的SQL命令
3、 show user;
select * from tab;
desc emp;
help index;
help conn;
4、保存缓冲区中的命令:
save c:/a.sql
@ c:/a.sql
5、set
set linesize 100
set pagesize 100
set wrap off;关闭自动回行
break on job;
6、备份SQL PLUS命令:
spool c:/a.txt;
select * from emp;
spool off;
六、安全管理
创建用户
(必须使用sys/system这两个用户创建其他用户)
create user user1 identified by aaa;
drop user user1;
权限
授权:
grant connect,resource to user1;
表级别权限:
grant all on scott.dept to user1;
角色:(权限的集合)
create role user_role;
grant connect,resource to user_role;
create user user2 identified by aaa;
grant user_role to user2;
七、表空间
虚拟的概念,逻辑概念
user1-------表空间中------数据文件
创建:
create tablespace myts_test datafile 'C:\first.dbf' size 10M
my_user
create user my_user identified by aaa default tablespace myts_test;
八、表的管理
1、数据类型
数字型:number(p,s);
字符型:char,varchar2
日期型:date('10-9月-2010')
大对象类型:clob(文本文件)
blob(4G)
2、创建表
create table my_tab(
id number(5),
name varchar2(10),
birth date
);
3、表的约束
主键:primary key
外键:foreign key
非空:not null
唯一:unique
检查:check
student
id(主键)
name(不能为空)
sex(只能男,女)
birth(不能为空)
mark
gid
grade
id(主键)
name(不能为空)
loc(不能重复)
4、修改表
添加新列:alter table student add age number(3);
删除 列: alter table student drop (age);
修改列数据类型:alter table student modify age number(3);
删除表:
delete from ttt ;(删除的是表中的数据,速度慢,数据可以恢复)
truncate table ttt;(删除表中的数据,速度快,数据不可以恢复)
drop table ttt;(删除表结构)
5、表的导入与出
转储文件(dump file)
导出:exp(c:\a.dmp)
导入:imp
第二部分 开发
SQL
结构化查询语言(Structured Query Language)IBM,ANSI,ISO指定了一个标准SQL-92
DDL(数据定义语言Data Definition Language) create drop alter
DML(数据操作语言Data Manipulation Language)insert,update,delete
DQL(数据查询语言Data Query Language)select
DCL(数据控制语言Data Control language)grant revoke commit rollback
DML(CRUD)
查询
a:基本查询
select * from emp;
select ename,deptno from emp;
select ename,deptno from emp e;
select ename as "职员姓名",deptno as "部门编号" from emp;
b:条件查询
select * from emp where sal>1500;
oracle中运算符
等值:=,>,>=,<,<=,!=(<>)
select * from emp where sal<>1600;
包含:in ,not in
select * from emp where job in('CLERK');
范围:between...and,not between...and
select * from emp where sal between 1500 and 2000;
null:select * from emp where comm is not null;
布尔连接:and,or,not
select * from emp where sal>1000 and comm is not null;
select * from emp where sal>1000 or comm is not null;
匹配测试:like,not like
通配符
%:表示任意数量的字符,包含没有
_:确切数量的任意字符
select * from emp where ename like '%A%';
select * from emp where ename like '__A%';
c:排序查询
order by,asc,desc
select * from emp order by deptno asc,sal desc;
d:分组查询
group by
聚合函数(max,min,sum,avg,count)
select avg(sal) from emp group by deptno;
select count(ename) from emp group by deptno;
select sum(sal) from emp group by deptno;
having
select avg(sal) as "平均工资",deptno as abc from emp group by deptno having avg(sal)>2000;
每个部门的每种岗位的平均和最低工资
select avg(sal),min(sal) from emp group by deptno,job;
每个部门的每种岗位的平均和最低工资,部门号,
岗位,平均工资大于2000的数据,按照部门号升序显示数据
select avg(sal),min(sal),deptno,job
from emp group by deptno,job having avg(sal)>2000 order by deptno asc;
注意:分组,筛选,排序一起使用的时候,先后顺序:group by,having,order by
e:多表查询
迪尔卡集现象
所有员工信息(姓名,工资,部门名字,部门地址)
n-1
联合查询:
内联:(等值查询)
select ename,sal,dname,loc from emp,dept where emp.deptno=dept.deptno;
select ename,sal,dname,log from emp inner join dept on emp.deptno=dept.deptno;
select ename,sal,dname,log from emp join dept on emp.deptno=dept.deptno;
结果一定是都满足条件的数据
外联:
左联左不丢,右联右不丢
左外联接:左表中满足条件不满足条件的数据,右表中满足条件的数据,右表中不满足条件的用null占位
select ename,dname from emp left join dept on emp.deptno=dept.deptno;
select ename,dname from emp left outer join dept on emp.deptno=dept.deptno;
select ename,dname from emp,dept where emp.deptno=dept.deptno(+);
右外联接:右表中满足条件不满足条件的数据,左表中满足条件的数据,左表中不满足条件的用null占位
在职员工姓名,员工所在的部门名,没有员工的部门名
select ename,dname from emp right join dept on emp.deptno = dept.deptno;
select ename,dname from emp right outer join dept on emp.deptno = dept.deptno;
select ename,dname from emp,dept where emp.deptno(+)=dept.deptno;
全外联接:所有数据
select ename,dname from emp full join dept on emp.deptno = dept.deptno;
select ename,dname from emp full outer join dept on emp.deptno = dept.deptno;
联合查询综合练习:
create table student( --学生表
studentid number(3) primary key, --学生编号
studentname varchar2(20) --学生的姓名
);
create table subject( --课程表
subjectid char(3) primary key, --课程编号
subjectname varchar2(20) --课程的名字
);
create table grade( --分数表
studentid number(3) references student(studentid), --学生id
subjectid char(3) references subject(subjectid), --课程id
mark number(3), --分数
primary key (studentid,subjectid) --联合主键
);
insert into student values (101,'张三');
insert into student values (102,'李云');
insert into student values (103,'张丹');
insert into subject values ('A01','C++');
insert into subject values ('A02','ASP');
insert into subject values ('A03','JAVA');
insert into grade values (101,'A01',59);
insert into grade values (101,'A02',72);
insert into grade values (101,'A03',90);
insert into grade values (102,'A01',75);
insert into grade values (102,'A02',91);
insert into grade values (103,'A01',71);
作如下4题
第一问:查询出以下信息
学号 学生姓名 课程名称 成绩 (要全部学生信息)
select a.studentid as "学号",
studentname as "学生姓名",
subjectname as "课程名称",
mark as "成绩"
from student a, subject b, grade c
where a.studentid = c.studentid
and b.subjectid = c.subjectid;
第二问:查询出以下信息
学号 学生姓名 课程名称 成绩(只显示每科最高分)
select a.studentid as "学号",
studentname as "学生姓名",
subjectname as "课程名称",
mark as "成绩"
from student a, subject b, grade c
where a.studentid = c.studentid
and b.subjectid = c.subjectid
and(
select count(*) from grade
where subjectid=b.subjectid
and mark >c.mark
)=0
第三问:查询出以下信息
学号 学生姓名 课程名称 成绩 (成绩大于60时的显示及格,小于60时的显示不及格)
select a.studentid as "学号",
studentname as "学生姓名",
subjectname as "课程名称",
decode(sign(mark-60),-1,'不及格','及格') as "成绩"
from student a, subject b, grade c
where a.studentid = c.studentid
and b.subjectid = c.subjectid
第四问:查询出以下信息
学号 学生姓名 (查询出课程超过1门以上学生的信息)
select a.studentid as "学号",
studentname as "学生姓名"
from student a, subject b, grade c
where a.studentid = c.studentid
and b.subjectid = c.subjectid
group by studentname
,a.studentid
having count(studentname)>1
HR用户中示例表的练习:
1、查询所有雇员的last_name,department_name,country_id
select last_name,department_name,c.country_id
from employees a,departments b,locations c
where a.department_id=b.department_id
and b.location_id = c.location_id;
2、部门是80的所有工作岗位,并输出部门的地点
select job_id,location_id
from employees e,departments d
where e.department_id = d.department_id
and e.department_id=80;
f:子查询
工资大于部门号30的平均工资员工信息
select * from emp where sal>(select avg(sal) from emp where deptno=30);
工资大于部门号30的最低工资员工信息
select * from emp where sal>(select min(sal) from emp where deptno=30);
工资大于部门号30的最高工资员工信息
select * from emp where sal>(select max(sal) from emp where deptno=30);
工资大于部门30的所有员工的工资的员工信息
all
select * from emp where sal>all(select sal from emp where deptno=30);
工资大于部门30的任意一个员工的工资的员工信息
any
select * from emp where sal>any(select sal from emp where deptno=30);
查询有员工的部门
in
select * from dept where deptno in(select distinct deptno from emp);
查询'KING'的同部门同事的信息,结果中不能包含‘KING’
select * from emp where deptno =
(select deptno from emp where ename='KING') and ename<>'KING';
查询'KING'的部下的信息
select * from emp where mgr=(select empno from emp where ename='KING');
查询与'ALLEN'相同部门的员工信息
select * from emp where deptno=(select deptno from emp where ename='ALLEN');
自联:
select e2.ename,e2.deptno,e2.sal
from emp e1,emp e2
where e1.deptno = e2.deptno
and e1.ename='ALLEN';
员工姓名,上级姓名
自联:
select e1.ename as "员工",e2.ename as "上级" from emp e1 ,emp e2 where e2.empno=e1.mgr
单行函数
1、distinct去掉重复数据
显示emp表中的职位
select distinct job from emp;
2、||连接符
按照如下格式显示数据:The Employee SMITH job is ClERK
select 'The Employee '||ename|| ' job is '||job as "员工的职位" from emp;
3、字符函数:
lower(),upper(),转换大小写
select upper(ename),lower(job) from emp;
concat(),length(),substr(str,2,2);
instr('abcde','a')---返回字符a的索引值是1
select concat(first_name,last_name) as "姓名",
length(last_name) as "名字长度"
from employees
where substr(last_name,2,1)='a';
4、数字函数
round()四舍五入
trunc()截取数字
mod()求余数
5、日期函数
sysdate,系统时间
next_day(sysdate,'星期五'),
next_day(sysdate,6),
当前时间下个星期五的日期
last_day();
显示McCain的入职周数
select round((sysdate-HIRE_DATE)/7 )as "入职周数"
from employees
where
last_name='McCain';
98年入职的员工的入职月份
select last_name,hire_date,trunc(hire_date,'MONTH')
from employees
where hire_date
like '%98';
6、to_char:转换函数
日期---字符
select to_char(sysdate,'fm yyyy Month DD') from dual;
select to_char(sysdate,'fm yyyy "年" Month DD "号"') from dual;
select to_char(sysdate,'fm yyyy "/" Month "/" DD') from dual;
select to_char(sysdate,'fm yyyy "-" Month "-" DD') from dual;
select ename,job,sal,to_char(hiredate,'fm yyyy"年"') from emp;
数字---字符
select ename,job,to_char(sal,'L99,999999,.99'),to_char(hiredate,'fm yyyy"年"') from emp;
select ename,job,to_char(sal,'$99,999,999.99'),to_char(hiredate,'fm yyyy"年"') from emp;
L:本地货币符号
$:美元符号
9:表示一位数
操作数据
插入:
create table emp_copy as select * from emp;
insert into emp_copy values(1000,'aaaa','CLERK',7839,'12-12月-2009',2000,200,10);
insert into emp_copy(empno,ename) values(1000,'aaaa');
insert into emp_copy select * from emp_copy;
修改:
update
update emp_copy set empno=rownum;
update emp_copy set sal=10000 wehre empno=200000;
删除: delete from emp_copy;
delete from emp_copy where empno=100;
delete from emp_copy where empno=(select empno from emp where ename='KING');
第三部分 数据库的其他对象
user,role,table
1、序列(sequence)
一组不重复的数字组成,用来产生唯一数字列值的数据库对象
create sequence my_seq1;
nextval
currval
升序序列
create sequence my_seq2
increment by 10--每次增长10
start with 10000--起始值
maxvalue 200000--最大值
cycle--自动循环
cache 20--放入缓存中序列值个数
降序序列
create sequence my_seq4
increment by -10
start with 200000
maxvalue 200000
minvalue 10000
cycle
cache 20(nocache)
2、视图(view)
简单视图(单基表视图)
是一个命名的查询,虚拟的表,表的透视图,视图并不存储数据
create view emp_view as select * from emp;
使用视图(CRUD)
复杂视图(多基表视图)
create view emp_dept
as
select ename,sal,dname,loc
from emp e,dept d
where e.deptno=d.deptno;
使用视图(CRUD)
不可以通过多基表视图进行修改数据
3、索引(index)
create index emp_ename_index on emp(ename);
create table emp_copy as select * from emp;--拷贝emp表
insert into emp_copy select * from emp_copy;--反复执行
alter table emp_copy modify empno number(8);--修改字段类型
update emp_copy set empno=rownum;--修改表中empno数据为行号,使值唯一
set timing on;--打开显示操作时间
select * from emp_copy where empno=500000;--创建索引之前使用时间
create index emp_copy_empno_index on emp_copy(empno);--创建索引
select * from emp_copy where empno=500000;--创建索引之后使用时间
drop index a;--删除索引
4、同义词(synonym)
scott.emp-----se
create synonym se for emp;
create synonym ed for emp_dept;(private)
private
public(必须是sys,system的身份才可以创建公用的同义词);
create public synonym ed2 for scott.emp_dept;????????
user,role,table,sequence,index,view,synonym
第四部分、PL/SQL
Procedual Language/Structured Query Language
语句块(匿名块)---存储过程,函数,触发器,包
语句块
工具:pl/sql developer,sqlplus
declare(可选)
--定义变量
begin
--执行的部门
exception(可选)
--处理异常
end;
--结束语句块
set serverout on--打开服务器的输出
第一个程序案例HelloWorld!!!
begin
dbms_output.put_line('HelloWorld!!!');
end;
定义变量,使用变量
declare
v_name varchar2(8);
v_age number(3);
v_sex boolean;
v_email string(20);
v_score integer;
begin
v_name:='张三';
v_age:=20;
v_sex:=true;
v_email:='aaa@126.com';
v_score:=80;
dbms_output.put_line(v_name||' '||v_age||' '||v_score||' '||v_email);
end;
注释:--单行注释、/*...*/多行注释
分支结构
--if结构
declare
v_num number;
v_str varchar2(4);
begin
v_num:=2;
if v_num=1 then
v_str:='A';
elsif v_num=2 then
v_str:='B';
else
v_str:='C';
end if;
dbms_output.put_line(v_str);
end;
--case结构
declare
v_num number;
v_str varchar2(10);
begin
v_num:=2;
case
when v_num=1 then v_str:='A';
when v_num=2 then v_str:='B';
when v_num=3 then v_str:='C';
else
v_str:='other';
end case;
dbms_output.put_line(v_str);
end;
--循环
--loop循环 1(使用 if 判断,跳出循环 )
declare
v_x number;
begin
v_x:=1;
loop
v_x:=v_x+1;
if v_x=10 then
exit;
end if;
dbms_output.put_line('循环体内v_x的值是:'||v_x);
end loop;
dbms_output.put_line('循环体外v_x的值是:'||v_x);
end;
--loop循环2(使用 when 判断,跳出循环)
declare
v_x number;
begin
v_x:=1;
loop--循环开始
v_x:=v_x+1;
exit when v_x=10;--使用 when
dbms_output.put_line('循环体内v_x的值是:'||v_x);
end loop;--循环结束
dbms_output.put_line('循环体外v_x的值是:'||v_x);
end;
--while循环
declare
v_x number;
begin
v_x:=1;
while v_x<=10 loop
v_x:=v_x+1;
dbms_output.put_line('循环体内v_x的值是:'||v_x);
end loop;
dbms_output.put_line('循环体外v_x的值是:'||v_x);
end;
--for 1循环 从小到大
declare
v_x number;
begin
v_x:=10;
for i in 1..v_x loop
dbms_output.put_line('循环体内i的值是:'||i);
end loop;
end;
--for 2循环 从大到小
declare
v_x number;
begin
v_x:=10;
for i in reverse 1..v_x loop--reverse 反向 循环
dbms_output.put_line('循环体内i的值是:'||i);
end loop;
end;
实用练习:
1、pl/sql与sql结合
DML(CRUD),不能写DDL,DCL
declare
v_ename varchar2(20);
begin
select ename into v_ename from emp where empno=&no;
dbms_output.put_line(v_ename);
end;
--&工具接受用户键盘的输入
--查询多个字段数据放入变量需要一 一对应
declare
v_ename varchar2(20);
v_sal number(10,2);
begin
select ename,sal into v_ename,v_sal from emp where empno=&no;
dbms_output.put_line(v_ename||' '||v_sal);
end;
--基本类型的变量只能放一条数据
declare
v_ename varchar2(20);
v_sal number(10,2);
begin
select ename,sal into v_ename,v_sal from emp;--会出现异常
dbms_output.put_line(v_ename||' '||v_sal);
end;
--变量的类型可以指定为表中字段的类型 使用 表名.字段名%type
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
select ename,sal into v_ename,v_sal from emp where empno=&no;
dbms_output.put_line(v_ename||' '||v_sal);
end;
--变量的类型还可以是一整条数据的类型 使用行类型作为变量类型 表名%rowtype
declare
v_data emp%rowtype;
begin
select * into v_data from emp where empno=&no;
dbms_output.put_line(v_data.ename||' '||v_data.sal||' '||v_data.deptno);
end;
--打印dept表中的数据
declare
v_dept_data dept%rowtype;--复合类型
v_dept_count number(4);
begin
select count(*) into v_dept_count from dept;
for i in 1..v_dept_count loop
select * into v_dept_data from
(select * from dept where rownum<=i minus select * from dept where rownum<=i-1);
dbms_output.put_line(v_dept_data.deptno||','||v_dept_data.dname||','||v_dept_data.loc);
end loop;
end;
异常:
系统异常:
no_data_found没找到数据
too_many_rows返回多行
zero_divede分母为0
dup_val_on_index唯一字段中插入相同的值.....
invalid_number输入数据有误出现的异常
value_error赋值操作异常
declare
v_ename emp.ename%type;
begin
select ename into v_ename from emp where empno=&no;
dbms_output.put_line(v_ename);
exception
when no_data_found then
null;
dbms_output.put_line('是否执行');
end;
自定义异常
declare
v_ename emp.ename%type;
v_my_exception exception;--自定义异常
begin
select ename into v_ename from emp where empno=&no;
if v_ename<>'SCOTT' then
raise v_my_exception;--抛 出异常
end if;
dbms_output.put_line(v_ename);
exception
when v_my_exception then--处理自定义异常
dbms_output.put_line('不是SCOTT');
when no_data_found then
dbms_output.put_line('无此员工');
when others then--处理其他异常
null;--不做接下来的任何操作
dbms_output.put_line('是否执行');
end;
命名块---语句块(名字)
可重用性
安全性
抽象,隐藏底层数据信息
不能移植(oracle---db2)
oracle------pl/sql
sql/server----T-SQL
db2-------sqlpl
存储过程(procedure)
create or replace procedure first_pro
is--is/as定义部分
begin
dbms_output.put_line('Hello Procedure');
end;
调用
1、通过命令调用
exec first_pro;
2、程序调用(pl/sql,java程序)
pl/sql语句块调用
begin
/// first_pro;
end;
/
具有插入功能的存储过程
create or replace procedure insert_dept
is
begin
insert into dept values(11,'English','上海');
end;
存储过程中的参数 (输入参数 )
create or replace procedure insert_dept(
v_deptno in dept.deptno%type,
v_dname dept.dname%type,
v_loc dept.loc%type
)
is
begin
insert into dept values(v_deptno,v_dname,v_loc);
end;
删除功能的存储过程
create or replace procedure delete_dept(
v_deptno dept.deptno%type
)
is
begin
delete from dept where deptno=v_deptno;
end;
修改功能的存储过程
create or replace procedure update_dept(
v_deptno dept.deptno%type,
v_dname dept.dname%type,
v_loc dept.loc%type
)
is
begin
update dept set dname=v_dname,loc=v_loc where deptno=v_deptno;
end;
查询的存储过程 ,输出参数
create or replace procedure find_emp(
v_empno emp.empno%type,
v_ename out emp.ename%type
)
is
begin
select ename into v_ename from emp where empno=v_empno;
end;
调用带有输出参数的存储过程
必须在语句块里调用 ,不能通过exec命令调用
declare
v_name emp.ename%type;
begin
find_emp(7788,v_name);
dbms_output.put_line(v_name);
end;
创建查询部门信息的存储过程
create or replace procedure find_dept(
v_deptno dept.deptno%type,
v_dname out dept.dname%type,
v_loc out dept.loc%type
)
is
begin
select dname,loc into v_dname,v_loc from dept where deptno=v_deptno;
end;
java-----调用存储过程
1、java连oracle(url,drivername,username,password),scott/aaa
项目中导入ojdbc14.jar文件
url:jdbc:oracle:thin:@localhost:1521:orcl
drivername:oracle.jdbc.OracleDriver
2、发送调用存储过程的语句,使用CallableStatement
CallableStatement cstmt = null;
cstmt = conn.prepareCall("{call find_dept(?,?,?)}");
cstmt.setInt(1, deptno);
//注册输出参数类型
cstmt.registerOutParameter(2, oracle.jdbc.OracleTypes.VARCHAR);
cstmt.registerOutParameter(3, oracle.jdbc.OracleTypes.VARCHAR);
//先执行存储过程
cstmt.execute();
//得到具体的数据
String dname = cstmt.getString(2);
String loc = cstmt.getString(3);
--参数既是输入参数也是输出参数
create or replace procedure avg_sal_dept(v_n in out number)
is
begin
select avg(sal) into v_n from emp where deptno=v_n;
end;
--调用 该存储过程
declare
v_d number(10);
begin
v_d:=10;
avg_sal_dept(v_d);
dbms_output.put_line(v_d);
end;
函数(function):
计算员工的年收入:12*sal+12*nvl(comm,0)
--创建函数
create or replace function empl_income(v_no emp.empno%type)
return number
is
v_income number(8,2);
begin
select (sal*12+nvl(comm,0)*12) into v_income from emp where empno=v_no;
return v_income;
end;
--调用函数
--作为sql的字句来调用
select empl_income(7788) from dual;
--函数 主要用于计算 ,头部必须有 return语句, 必须要有返回值
程序包(package)
create package mypackage01 is
procedure find_dept(
v_deptno dept.deptno%type,
v_dname out dept.dname%type,
v_loc out dept.loc%type
);
function empl_income(v_no emp.empno%type)return number;
end;
pl/sql中的包内容(过程或函数),只能声明,不实现
创建包体(在包体中实现包中没有实现的过程或函数)
create package body mypackage01 is
procedure find_dept(
v_deptno dept.deptno%type,
v_dname out dept.dname%type,
v_loc out dept.loc%type
)
is
begin
select dname,loc into v_dname,v_loc from dept where deptno=v_deptno;
end;
function empl_income(v_no emp.empno%type)return number
is
v_income number(8,2);
begin
select (sal*12+nvl(comm,0)*12) into v_income from emp where empno=v_no;
return v_income;
end;
end;
在包中可以定义变量,类型,过程,函数,游标
变量:
定义:变量名 类型
标量类型:varchar2,number,date.......
复合类型:%type,%rowtype,record(记录类型),table(表格类型)
record:
创建程序包,在包中定义类型
create package mypackage02 is
type v_record is record(v_ename emp.ename%type,v_sal emp.sal%type,v_hiredate emp.hiredate%type);
end;
--语句块中使用记录类型
declare
--type v_record is record(v_ename emp.ename%type,v_sal emp.sal%type,v_hiredate emp.hiredate%type);
--使用包中的类型
v_data mypackage02.v_record;
begin
select ename,sal,hiredate into v_data from emp where empno=&no;
dbms_output.put_line(v_data.v_ename||','||v_data.v_sal||','||v_data.v_hiredate);
end;
参照类型:游标
游标:(cursor)
游标是一种pl/sql中的控制结构,可以对sql语句的处理进行显示控制,便于对表数据进行逐条处理,
可以显示遍历结果集,可以通过游标向外部应用程序传递一个结果集
处理游标流程
(1)声明游标
cursor cur_name is selelct......
(2)打开游标
open cur_name;
(3)从游标中抓取数据
fetch cur_name into v_data....
(4)关闭游标
close cur_name
--使用游标案例
declare
cursor my_cur is select * from emp;
v_data emp%rowtype;
begin
open my_cur;
fetch my_cur into v_data;
dbms_output.put_line(v_data.ename||','||v_data.sal);
fetch my_cur into v_data;
dbms_output.put_line(v_data.ename||','||v_data.sal);
close my_cur;
end;
--使用loop循环处理
declare
cursor my_cur is select * from emp;
v_data emp%rowtype;
begin
open my_cur;
loop
fetch my_cur into v_data;
exit when my_cur%notfound;
dbms_output.put_line(v_data.ename||','||v_data.sal);
end loop;
close my_cur;
end;
使用 while循环
declare
cursor my_cur is select * from emp;
v_data emp%rowtype;
begin
open my_cur;
fetch my_cur into v_data;--先抓取再循环 ,%found当没有对游标数据进行抓取的时候返回 null
while my_cur%found
loop
dbms_output.put_line(v_data.ename||','||v_data.sal);
fetch my_cur into v_data;
end loop;
close my_cur;
end;
使用 for循环 (遍历游标,不用显示打开游标,抓取游标,关闭游标)
declare
cursor my_cur is select * from emp;
v_data emp%rowtype;
begin
for i in my_cur loop
dbms_output.put_line(i.ename||','||i.sal);
end loop;
end;
游标变量
declare
type cur_type is ref cursor;--定义类型为参照类型
v_data cur_type;--定义变量,类型为定义的类型
v_ar emp%rowtype;
begin
open v_data for select * from emp;
loop--使用循环处理游标
fetch v_data into v_ar;
exit when v_data%notfound;
dbms_output.put_line(v_ar.ename);
end loop;
close v_data;
end;
编写一个过程,传入表名,返回所有数据
java调用存储过程
1、调用没有参数的存储过程
2、有输入参数
3、有输入参数,输出参数
4、输出参数为游标类型
--使用存储过程实现oracle分页,并在JAVA中调用
--oracle分页 rownum(mysql:limit,sql server:top) 不能用 minus xxxxxx
pageSize(5)
pageCurrent(3)
pageSize*pageCurrent
(pageCurrent-1)*pageSize+1
select * from emp;
select e.*,rownum rn from(select * from emp) e;
select e.*,rownum rn from(select * from emp) e where rownum<=10
select * from(select e.*,rownum rn from(select * from emp) e where rownum<=10) where rn>=6;
--创建程序包,包中定义游标类型
create or replace package package03 is
type cur_type is ref cursor;
end;
--存储过程
create or replace procedure page_pro(
table_name varchar2,
pageSize in number,
pageCurrent in number,
v_data out package03.cur_type,
maxpage out number)
is
v_page_sql varchar2(500);
v_counts number(6);
v_sql varchar2(50);
begin
v_page_sql:='select * from(select e.*,rownum rn from(select * from '||table_name||') e where rownum<='||pageSize*pageCurrent||') where rn>='||((pageCurrent-1)*pageSize+1);
open v_data for v_page_sql;
v_sql:='select count(*) from '||table_name;
execute immediate v_sql into v_counts;--execute,immediate立即执行 sql语句
if mod(v_counts,pageSize)=0 then
maxpage:=v_counts/pageSize;
else
maxpage:=v_counts/pageSize+1;
end if;
end;
--JDBC调用存储过程