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语句

--编写过程,能够输入username,并循环加入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循环

--编写过程,可输入username,并循环加入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:hin@127.0.0.1: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;

 

 注意:视图和视图之间能够做复杂联合查询

 

 改动视图:

 

 删除视图:

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

  1. Oracle学习笔记七 锁

    锁的概念 锁是数据库用来控制共享资源并发访问的机制. 锁用于保护正在被修改的数据 直到提交或回滚了事务之后,其他用户才可以更新数据 对数据的并发控制,保证一致性.完整性.

  2. 玩转oracle学习第五天

     1.上节回想 2.维护数据的完整性 3.管理索引 4.管理权限和角色 1.掌握维护oracle数据完整性的技巧  2.理解索引的概念,会建立索引  3.管理oracle的权限和角色   介绍:维 ...

  3. oracle学习篇七:更新操作、事务处理

    ----------------1.数据库更新操作----------------------------- select * from tab;--查询表 drop table siebel_use ...

  4. 玩转oracle学习第六天

     1.上节回想 2.PL/SQL的介绍 3.PL/SQL的基础 理解oracle的pl/sql概念 掌握PL/SQL编程技术(包含编写过程,函数,触发器.包... ) PL/SQL是什么? PL/ ...

  5. Oracle学习(七)游标

    一.简介 定义 实质上是数据集,类似数组一样,把查询的数据集存储在内存当中. 使用时可以通过游标指向其中一条记录,也可以通过循环游标达到循环数据集的目的. 游标的种类 显式游标: 使用之前必须得先声明 ...

  6. Oracle学习笔记(七)

    九.高级查询(分组,子查询)查询升级版: 需要用到三张表员工表: desc emp EMPNO 员工号 ENAME 员工姓名 JOB 员工职位 MGR 老板员工号 HIREDATE 员工入职日期 SA ...

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

    oracle学习门户系列七 网络管理和配置 们学习了模式和用户.包含模式定义以及模式的作用. 这篇我么来看下ORACLE数据库中的网络管理和配置.只是这篇好像和上篇没有继承啊.这怎么看? Ok,事实上 ...

  8. Oracle 学习(scott方案)

      Oracle学习中,重点是sql语句的学习,而所有的sql语句都要在scott用户下完成. 熟悉这个用户下的四张表,是必要的. 查看所有表名: SELECT * FROM tab; 查看每张表的结 ...

  9. SpringBoot+Shiro学习(七):Filter过滤器管理

    SpringBoot+Shiro学习(七):Filter过滤器管理 Hiwayz 关注  0.5 2018.09.06 19:09* 字数 1070 阅读 5922评论 1喜欢 20 先从我们写的一个 ...

随机推荐

  1. Android Bundle存储数据类型

    曾经被问到这样一个问题:Bundle能存哪些数据类型,不能存哪些数据类型? 当时那个汗啊,因为,平常使用Bundle,要么使用基本数据类型,要么序列化自定义的Class,那到底能存哪些类型,不能存哪些 ...

  2. 小程序target与currentTarge区别

        文章来源:刘俊涛的博客 欢迎关注,有问题一起学习欢迎留言.评论

  3. Linux的网卡由eth0变成了eth1怎么办?

    Linux的网卡由eth0变成了eth1怎么办? Linux的网卡由eth0变成了eth1,如何修复 使用wmware安装了linux,安装成功后,使用的网卡是eth0,没有eth1.但是用过一段时间 ...

  4. OpenERP 负载平衡

    OpenERP 7.0 带来了许多新特性,架构上也有许多改进.其中可配置 worker 参数,可使 OpenERP 运行在多进程模式,突破GIL的限制,有效利用了现代多核CPU的性能.但默认情况下,O ...

  5. Asp.net Mvc (Filter及其执行顺序)

    应用于Action的Filter 在Asp.netMvc中当你有以下及类似以下需求时你可以使用Filter功能判断登录与否或用户权限,决策输出缓存,防盗链,防蜘蛛,本地化设置,实现动态Actionfi ...

  6. ie上画圆饼图

    概述 主要运用到CSS3的transform.js.jq实现饼状图效果 详细 代码下载:http://www.demodashi.com/demo/10579.html 一.准备工作 1.主要运用到C ...

  7. 一道SQL题

    原题:大池子博客 给定一个access_time表,它记录了用户每个月访问网站的次数,包括三个域:用户.时间.次数.注意表中可能包含用户在1月份的多条记录. 要求查询用户.月份.月累计.总共累计四项的 ...

  8. 使用bootstrap标签页

    关键字:使用标签页,静态调用html页面(使用iframe内联框架) 完整代码如下: <!DOCTYPE html> <html lang="en"> &l ...

  9. Windows Server 2008的远程控制修改端口,谨防非法远程连接

    1.首先在Windows Server 2008服务器系统桌面上依次单击“开始”/“运行”命令,在弹出的系统运行对话框中,输入字符串命令“regedit”,单击回车键后,打开对应系统的注册表编辑界面; ...

  10. jquery插件--ajaxfileupload.js上传文件原理分析

    英文注解应该是原作者写的吧~说实话,有些if判断里的东西我也没太弄明白,但是大致思路还是OK的. jQuery.extend({ createUploadIframe: function (id, u ...