玩转oracle学习第七天



1.上节回顾

2.PL/SQL的进阶

3.oracle的视图

4.oracle的触发器

目标:

1.掌握PL/SQL的高级用法(能编写分页过程模块,下订单过程模块。。。)

2.会处理oracle常见的例外

3.会编写oracle各种触发器

4.理解视图的概念并能灵活使用视图

任何计算机语言都有各种控制语句,在PL/SQL中也存在这样的控制结构

在本部分学习完毕后,希望大家达到:

1)使用各种if

2)使用循环结构

3)使用控制语句 goto 和 null;

条件分支语句:

if then end if

if then else end if

if then elsif else end if

简单的条件判断:

案例:编写一个过程,可以输入一个雇员名,如果该雇员的工资低于

2000,就给该雇员工资增加10%

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 < 2000 then

update emp set sal=sal+sal*10 where ename = spName;

end if;

end;

/

调用:

exec sp_pro6(‘scott‘);

二重条件分支:if - then - else

编写一个过程,可以输入一个雇员名,如果该雇员的补助不是0,则工资添加100

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 <> 0 then

update emp set comm=comm+100 where ename = spName;

else

update emp set comm=comm+200 where ename = spName;

end if;

end;

/

--编写过程,给不同职位的员工添加不同的工资

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 ...

elsif

update ...

else

update ...

end if;

end;

循环语句 -loop

PL/SQL中的循环语句,最简单的循环语句是loop语句

--编写过程,可以输入用户名,并循环添加10个用户到user表中,

用户编号从1开始增加

create or replace procedure sp_pro6(spName varchar2) is

v_num number := 1;

begin

loop

insert into users values(v_num,spName);

--判断是否要退出循环

exit then v_num=10; --等于10就要退出循环

--自增

v_num := v_num+1;

end loop;

end;

exec sp_pro6(‘你好‘);

循环语句:while循环

--编写过程,可输入用户名,并循环添加10个用户到users表中,

用户编号从11开始增加

while v_num <= 20 loop

insert into user values(v_num,spName);

v_num:=v_num+1;

end loop;

end;

循环语句:for循环

基本for循环的基本结构如下:

begin

for i in reverse 1 .. 10 loop

insert into user values(i,‘世阳‘)

end loop;

end;

goto语句和null语句

goto end_loop;

<<end_loop>>

goto案例:

declare

i int := 1;

begin

loop

dbms_output.put_line(‘输出i=‘||i)

if i=10 then

goto end_loop;

end if;

i := i+1;

end loop;

end;

/

if

...

else

null;--表示什么都不做

分页过程:

无返回值的存储过程

create table book(bookId number,bookName varchar2(50),publishHouse varchar2(50));

--编写过程:

--in代表这是一个输入参数,默认为in

--out:表示一个输出参数

create or replace sp_pro7(spBookId in number,spbookName in varchar2,sppublishHouse in varchar2) is

begin

insert into book values(spBookId,spbookName,sppublishHouse);

end;

编写java程序调用无返回值的过程

//1.加载驱动

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection ct=DriverManager.getConnection("jdbc:oracle:[email protected]:1521","scott","tiger");

//2.创建CallableStatement

CallableStatement cs = ct.prepareCall("{call sp_pro7(?,?,?)}");

//给?赋值

cs.setInt(1,10);

cs.setString(2,"笑傲江湖");

cs.setString(3,"人民出版社");

//执行

cs.execute();

编写有返回值的存储过程(非列表)

create or replace procedure sp_pro8

(spno in number,spName out varchar2,spSal out number,spJob out varchar2)is

begin

select ename, sal, job into spName, spSal, spJob from emp where empno=spno;

end;

java如何获取有返回的存储过程的数据

//

callableStatement cs = ct.prepareCall("{call sp_pro8(?,?,?,?)}");

//给第一个?赋值

cs.setInt(1,7788);

//给第二个?赋值

cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);

cs.registerOutParameter(3,oracle.jdbc.OracleTypes.DOUBLE);

cs.registerOutParameter(4,oracle.jdbc.OracleTypes.VARCHAR);

//执行

cs.execute();

//区返回值要注意?的顺序

string name=cs.getString(2);

double sal =cs.getDouble(3);

string job=cs.getString(4);

编写一个过程,输入部门号,返回该部门所有雇员信息。此时用一般的参数是不可以的,需要使用package了,所以要分为两部分

(1)创建一个包,如下:

--返回结果集的过程

--创建一个包,包中定义了一个游标,类型test_cursor

create or replace package testpackage as

type test_cursor is ref cursor;

end testpackage;

(2)创建存储过程

create or replace procedure sp_pro9(spNo in number,p_cursor out testpackage.test_cursor) is

begin

open p_cursor for select * from emp where deptno = spNO;

end;

java程序调用:

//创建CallableStatement

CallableStatement cs=ct.prepareCall("{call sp_pro9(?,?)}");

//给?赋值

cs.SetInt(1,10);

cs.registerOutParameter(2,oracle.jdbc.OracleTypes.CURSOR);

//执行

cs.execute();

ResultSet rs = (ResultSet)cs.getObject(2);

while(rs.next())

{

System.out.println(rs.getInt(1)+"  "+ra.getString(2));

}

编写分页过程

输入表名,每页显示记录数,当前页,返回总记录数,总页数

--oracle的分页:

select t1.*,rownum rn from(select * from emp) t1 where rownum<=10;

--在分页时,大家可以把下面的sql语句当做一个模板使用

select * from (select t1.*,rownum rn from(select * from emp order by sal) t1 where rownum<=10) where rn>=6;

--开发一个包

create or replace package testpackage as

type test_cursor is ref cursor;

end testpackage;

--开始编写分页的过程

create or replace procedure fenye(tableName in varchar2,

pagesize  in number,--一页显示多少条记录

pageNow   in number,--第几页

myrows    out number, --总记录数

myPageCount out number,--总页数

p_cursor out testpackage.test_cursor) is

--定义部分

--定义sql语句 字符串

v_sql varchar2(1024);

--定义两个整数

v_begin number := (pageNow-1)*pagesize+1;

v_end   number := pageNow*pagesize;

begin

--执行部分

v_sql := ‘select * from (select t1.*,rownum rn from(select * from ‘||tbaleName ||‘) t1 where rownum<=‘||v_end ||‘) where rn>=‘ ||v_begin;

--把游标和sql关联

open p_cursor for v_sql;

--计算myrows和myPageCount

--组织一个sql

v_sql := ‘select count(*) from ‘ || tableName;

--执行sql,并把返回的值,赋给myrows

execute immediate v_sql into myrows;

--计算myPageCount

if mod(myrows,Pagesize)=0 then

myPageCount:=myrows/Pagesize;

else

myPageCount:=myrows/Pagesize+1

end if;

--关闭游标

--close p_cursor;

end;

/

java程序来验证分页过程显示的正确性

//测试分页

//加载驱动

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection ct=DriverManager.getConnection("...");

CallableStatement cs=ct.prepareCall("{call fenye(?,?,?,?,?,?)}");

cs.setString(1,"emp");

cs.setInt(2,5);

cs.setInt(3,1);

cs.registerOutParameter(4,orace.jdbc.OracleTypes.INTEGER);

cs.registerOutParameter(5,oracle.jdbc.OrcleTYpes.INTEGER);

cs.registerOutParameter(5,oracle.jdbc.OrcleTYpes.CURSOR);

cs.execute();

//获取总记录数/这里要注意,getInt(4),其中4,是由该参数的位置决定的

int rowNum = cs.getInt(4);

int pageCount = cs.getINt(5);

ResultSet rs = (ResultSet)cs.getObject(6);

while(rs.next())

{

...

}

--新的需求,按照薪水由低到高进行排序

PL/SQL的进阶  --例外处理

例外的分类

例外传递

--例外案例

写一个块:

declare

--定义

v_ename emp.ename%type;

begin

--

select ename into v_name from emp where empno=&gno;

dbms.output.put_line(v_ename);

exception

when no_data_found then

dbms.output.put_line(‘编号没有‘);

end;

处理预定义例外:

PL/SQL提供了20过个预定义的例外:

case_no_found

case  when ... when ... end case

dup_val_on_index

在试图在不合法的游标上执行操作时,会触发该例外

例如:试图从没有打开的游标提取数据,或是关闭没有打开的游标,则会

触发该例外

invalid_number

当输入的数据有误时,会触发该例外

比如:

too_many_rows

当执行select into语句的时候,如果返回超过了一行,则会触发该异常

zero_divide

value_error

当执行赋值操作时,如果变量的长度不足以容纳实际数据

处理自定义例外

预定义例外和自定义例外都是与oracle错误相关的,并且

--自定义例外

create or replace procedure ex_test(spNo number)

is

--定义一个例外

myex exception;

begin

--更新用户sal

update emp set sal=sal+1000 where empno=spNo;

--sql%notfound这里表示没有update

--raise myex;触发myex

if sql%notfound then

raise myex;

end if;

exception

when myex then

dbms_output.put_line(‘没有更新任何用户‘);

end;

/

exec ex_test(56);

oracle视图

介绍:

视图是一个虚拟表,其内容由查询定义,同真实的表一样,视图包含一系列带有名称的列

和行的数据。但是,视图并不在数据库中以存储数据值集形式存在

例如两张表 emp表和dept表

1.如果要显示各个雇员的名字和他所在部门的名称,必须用两张表?

2.假定管理员创建一个用户,现在只希望该用户查询sal<1000的那些雇员?

视图和表的区别:

1.表需要占用磁盘空间,视图不需要

2.视图没有索引,表有索引,所以视图查询较表速度慢

3.使用视图可以简化复杂查询

4.使用视图有利于提高安全性

创建视图:

--把emp表的 sal<1000的雇员 映射到该视图(view)

create view myView as select * from emp where sal<1000;

--视图一旦创建成功,就可以当成一个普通表来使用

--为简化操作,用一个视图解决 显示雇员编号,姓名和部门名称,并且为可读视图

create view myView1 as select emp.empno,emp.ename,dept.dname from emp,dept where emp.deptno=dept.deptno with read only;

注意:视图和视图之间可以做复杂联合查询

修改视图:

删除视图:

时间: 2024-10-12 23:53:50

玩转oracle学习第七天的相关文章

玩转oracle学习第五天

 1.上节回顾 2.维护数据的完整性 3.管理索引 4.管理权限和角色 1.掌握维护oracle数据完整性的技巧 2.理解索引的概念,会建立索引 3.管理oracle的权限和角色 介绍:维护数据的完整性 数据完整性用于确保数据库数据遵从一定的商业和逻辑guize, 在oracle中,数据完整性可以使用约束,触发器, 应用程序(过程,函数)三种方式来实现,在这三种方法中,因为约束易于维护, 并且具有最好的性能,所以作为维护数据完整性的首选 约束:约束用于确保数据库数据满足特定的商业规则, 在o

玩转oracle学习第六天

 1.上节回顾 2.PL/SQL的介绍 3.PL/SQL的基础 理解oracle的pl/sql概念 掌握PL/SQL编程技术(包括编写过程,函数,触发器,包...) PL/SQL是什么? PL/SQL(procedural language/sql)是oracle在标准的sql语言的扩展,PL/SQL不仅允许 嵌入sql语言, 数据库:编写存储过程,函数,触发器,使用的是PL/SQL语言,PL/SQL简化了复杂度 增加程序的模块化,减小网络的传输的开销,提高安全性,提高程序的运行效率 1.过

Oracle学习笔记七 锁

锁的概念 锁是数据库用来控制共享资源并发访问的机制. 锁用于保护正在被修改的数据 直到提交或回滚了事务之后,其他用户才可以更新数据 对数据的并发控制,保证一致性.完整性.             并行性 -允许多个用户访问同一数据 一致性 - 一次只允许一个用户修改数据 完整性 - 为所有用户提供正确的数据.如果一个用户进行了修改并保存,所做的修改将反映给所有用户 锁的类型 行级锁:对操作的数据行进行锁定,防止其他用户(连接)进行修改. 表级锁:对整个表进行锁定. 行级锁 对正在被修改的行进行锁

玩转oracle学习第四天

1.上节回顾 2.数据库管理员 3.数据库的逻辑备份与恢复 4.数据字典和动态性能视图 5.管理表空间和数据文件 1.了解oracle管理员的基本职责 2.掌握备份和恢复数据库/表的方法 3.理解表空间,数据字典,性能视图数据库管理员dba,对于一个小的数据库,一个dba就够了,但是对于一个大的数据库可能需要多个dba分别担负不同的管理职责,一个dba的主要工作: 职责: (1)安装和升级oracle数据库 (2)建库,表空间,表,视图,索引 (3)制定并实施备份与恢复计划 (4)数据库权限管理

oracle学习篇七:同义词

Oracle数据库中提供了同义词管理的功能.Oracle同义词是数据库方案对象的一个别名,经常用于简化对象访问和提高对象访问的安全性. 在Oracle中对用户的管理是使用权限的方式来管理的,也就是说,如果我们想使用数据库,我们就必须得有权限,但是如果是别人将权限授予了我们,我们也是能对数据库进行操作的,但是我们必须要已授权的表的名称前键入该表所有者的名称,所以这就是比较麻烦的,遇到这种情况,我们该怎么办呢?创建个Oracle同义词吧!这样我们就可以直接使用同义词来使用表了. 1.同义词的概念Or

oracle学习篇七:约束

----约束------- --1.主键约束--唯一标识,不能为空,通常用于ID--1>创建主键create table person(id varchar2(20) primary key,name varchar2(50),birthday date,sex varchar2(2) default '男');insert into person(id,name,birthday,sex)values(1,'zhangsan',to_date('1988-05-11','yyyy-mm-dd'

Oracle学习笔记(七)

九.高级查询(分组,子查询)查询升级版: 需要用到三张表员工表: desc emp EMPNO 员工号 ENAME 员工姓名 JOB 员工职位 MGR 老板员工号 HIREDATE 员工入职日期 SAL 员工月薪 COMM 员工奖金 DEPTNO 员工所在部门部门号 查看当前用户: show users; select * from emp;部门表: desc dept deptno 部门号 dname 部门名称 LoC 部门地点 select * from dept;工资级别表: desc s

Oracle学习记录 七 继续接六的

下面是转换函数 to_char select to_char(sysdate,'yyyy') from dual; select to_char(sysdate,'fmyyyy-mm-dd') from dual; select to_char(sysdate,'yyyy-mm-dd') from dual; select to_char(sysdate, 'DDD') from dual;    一年中的第几天 select to_char(sysdate, 'DD') from dual; 

7.oracle学习门户系列七---网络管理和配置

oracle学习门户系列七 网络管理和配置 们学习了模式和用户.包含模式定义以及模式的作用. 这篇我么来看下ORACLE数据库中的网络管理和配置.只是这篇好像和上篇没有继承啊.这怎么看? Ok,事实上呢-..咳咳-..我们继续往下走 数据库的网络配置是比較基础可是也是很重要的.假设一个数据库连不上外部的世界:那么他就是一个孤立的资源,基本上就能够确认这是个无用的数据库系统. 我们在数据库定义中以前讲过,数据库是须要有多用户分享的,没有网络何来分享呢?对不正确.那肯定不是数据库了嘛. 前面摘要已经