回顾:

  1.record类型

    定义record类型,声明变量,保存s_dept表中id = 31部门信息

declare
/* 定义record类型 */
type deptrecord is record(
id number,
name s_dept.name%type,
r_id number
);
/* 声明变量 */
var_dept deptrecord;
var_id number:=&id;
begin
select * into var_dept from s_dept where id=var_id;
dbms_output.put_line(var_dept.id||','||
var_dept.name||','||
var_dept.r_id);
end;

  

  2.动态SQL

    使用动态SQL语句,删除 testdsql 表中指定id 信息

declare
sqlstr varchar2(100);
var_id number:=1;
begin
-- sqlstr:='delete from testdsql_zsm_00 where id='
-- ||var_id;
sqlstr:='delete from testdsql_zsm_00 where id=:b0';
dbms_output.put_line(sqlstr);
execute immediate sqlstr using var_id;
commit;
end;
     

1.游标:

  1.1概念:

      游标是映射在结果集中一行数据的位置指针或位置实体。

  1.2作用:

      处理多行结果集!

      用户可以通过游标访问多行结果集中的任何一行数据,即可以对该行数据做操作,比如,把数据提取出来

  1.3使用游标步骤:

    1) 声明游标

       在声明区声明游标名

       cursor 游标名 is select语句;

       var_emp empcursor%rowtype;//声明游标变量

2)打开游标

       在执行区打开游标

       open 游标名;

    3)提取数据

       执行区提取数据

       fetch 游标名 into 游标变量;

    4)关闭游标         

       当提取和处理数据结束后,应该及时关闭游标释放系统资源

       close 游标名;

   1.4使用游标 读取s_emp 表中的全部数据     

      declare
/* 声明游标 */
cursor empcursor is select * from s_emp;
/* 声明变量 */
var_emp empcursor%rowtype;
begin
/* 打开游标 */
open empcursor;
/* 提取数据 */
fetch empcursor into var_emp;
dbms_output.put_line(var_emp.id||','||
var_emp.first_name||','||
var_emp.salary);
fetch empcursor into var_emp;
dbms_output.put_line(var_emp.id||','||
var_emp.first_name||','||
var_emp.salary);
fetch empcursor into var_emp;
dbms_output.put_line(var_emp.id||','||
var_emp.first_name||','||
var_emp.salary);
/* 关闭游标 */
close empcursor;
end;

  1.5游标属性

    found     提取到数据,为真;没有提取到,则为假       在open之前,返回非法游标,fetch之前返回null

    notfound   没提取到数据,为真;提取到,则为假          ..  ..  ..  ..

    isopen    游标是否是打开状态,打开返回真,失败返回假

    rowcount   游标的偏移量   没有打开返回非法游标

  1.6使用简单循环   配合  notfound 属性 遍历游标  

declare
/* 声明游标 */
cursor empcursor is select * from s_emp;
/* 声明变量 */
var_emp empcursor%rowtype;
begin
/* 打开游标 */
open empcursor;
/* 循环提取数据 */
loop
fetch empcursor into var_emp;
exit when empcursor%notfound;
dbms_output.put_line(var_emp.id||','||
var_emp.first_name||','||
var_emp.salary);
end loop;
/* 关闭游标 */
close empcursor;
end;

  1.7使用while循环 配合found属性 遍历游标

declare
/* 声明游标 */
cursor empcursor is select * from s_emp;
/* 声明变量 */
var_emp empcursor%rowtype;
begin
/* 打开游标 */
open empcursor;
/* 循环提取数据 */
fetch empcursor into var_emp;
while empcursor%found loop
dbms_output.put_line(var_emp.id||','||
var_emp.first_name||','||
var_emp.salary);
fetch empcursor into var_emp;
end loop;
/* 关闭游标 */
close empcursor;
end;

  1.8使用for循环遍历游标

      for循环(智能循环) (自动打开游标、提取数据、关闭游标)

declare
cursor empcursor is select * from s_emp;
begin
for var_emp in empcursor loop
dbms_output.put_line(var_emp.id||','||
var_emp.first_name||','||
var_emp.salary);
end loop;
end;

   1.9带参游标

      参数的数据类型不能包含长度或精度的修饰,但是可以使用%type

      声明:

          cursor 游标名(形参列表) is   select语句 where .... ;

      传参: 在打开游标时传实参

          open 游标名(实参列表);

declare
cursor empcursor(var_id number)
is select * from s_emp where id>var_id;
begin
for var_emp in empcursor(10) loop
dbms_output.put_line(var_emp.id||','||
var_emp.first_name||','||
var_emp.salary);
end loop;
end;

   1.10参考游标 ref cursor

      动态SQL + 游标

参考游标的使用步骤:
sqlstr := 'select * from s_emp';
1) 定义一个参考游标类型
type 参考游标类型名 is ref cursor;
2) 声明参考游标类型变量
var_empcursor 参考游标类型名;
3) 把动态sql语句和参考游标变量结合
open var_empcursor for sqlstr;
...... 案例:使用参考游标 遍历s_emp表中的全部数据
declare
sqlstr varchar2(100);
type emprefcursor is ref cursor;
var_empcursor emprefcursor;
var_emp s_emp%rowtype;
begin
sqlstr:='select * from s_emp';
open var_empcursor for sqlstr;
loop
fetch var_empcursor into var_emp;
exit when var_empcursor%notfound;
dbms_output.put_line(var_emp.id||','||
var_emp.first_name||','||
var_emp.salary);
end loop;
close var_empcursor;
end; 带有占位符的sql语句
declare
sqlstr varchar2(100);
type emprefcursor is ref cursor;
var_empcursor emprefcursor;
var_emp s_emp%rowtype;
begin
sqlstr:='select * from s_emp where id>:b0';
-- using后可以使用变量,也可以使用值。一般用变量
open var_empcursor for sqlstr using 10;
loop
fetch var_empcursor into var_emp;
exit when var_empcursor%notfound;
dbms_output.put_line(var_emp.id||','||
var_emp.first_name||','||
var_emp.salary);
end loop;
close var_empcursor;
end;

2.PLSQL中的异常

  2.1 系统预定义异常

    Oracle 系统自身为用户提供可以在PLSQL中使用的预定义异常,用于检查用户代码失败的一般原因。

    系统预定义异常由系统定义和引发,用户只需根据名字捕获和处理异常

案例:
declare
var_name varchar2(25);
var_id number:=&id;
begin
select first_name into var_name from s_emp
where id = var_id;
select first_name into var_name from s_emp
where first_name like 'M%';
dbms_output.put_line(var_name);
exception
when no_data_found then
dbms_output.put_line('no emp');
when others then
dbms_output.put_line(sqlcode||'.....'||sqlerrm);
end;

     常用的异常:

    no_data_found :     select ..into 语句没有返回行

    too_many_rows:       select..into 语句返回多于一行的结果集

    invalid_cursor:        非法游标

    cursor_already_open:     游标已打开

    dup_val_on_index:     唯一索引对应的列上有重复值

    zero_divide:      除数为0

案例:处理多个异常
declare
var_name varchar2(25);
var_id number:=&id;
begin
select first_name into var_name from s_emp
where id = var_id;
select first_name into var_name from s_emp
where first_name like 'M%';
dbms_output.put_line(var_name);
exception
when no_data_found then
dbms_output.put_line('no emp');
when too_many_rows then
dbms_output.put_line(' too many rows');
when others then
dbms_output.put_line(sqlcode||'.....'||sqlerrm);
end;

  2.2自定义异常:

     2.2.1 定义异常的步骤: 

        1)定义异常

            异常名 exception ;

        2)根据条件引发异常

            if 引发异常条件 then

              raise 异常名;

            end if;

        3)捕获异常和处理异常

            when 异常名 then

               处理异常

    2.2.2 案例:更新员工表中指定员工的工资,员工不存在时提示异常

declare
var_id s_emp.id%type:=&id;
/* 定义异常 */
no_result exception;
begin
update s_emp set salary=salary+500 where id=var_id;
if sql%notfound then
raise no_result;
end if;
commit;
exception
when no_result then
dbms_output.put_line('no result');
end;

      隐式游标:在执行一个SQL语句时,Oracle会自动创建一个隐式游标。这个游标是内存中为处理该条SQL语句的工作区。

      隐士游标只要用于处理数据操作语句(insert、delete、update)的执行结果

3.存储过程 procedure

 3.1匿名块和有名块

  匿名块:

    匿名块不保存在与数据库中;每次使用都要 进行编译;不能在其他块调用

  有名块:

    可以存储在数据库中;可以在任何需要的地方调用

    

    有名块包括:procedure          function                     package                trigger

 3.2存储过程的创建

  语法:

    create [ or replace ] procedure 过程名 [ (参数列表) ]

    is|as

       --临时变量

    begin

    exception

    end;

 3.3无参过程的创建和调用

  1)创建:输出两数中的较大值

 create or replace procedure getmax_zsm_00
is
var_a number:=10;
var_b number:=100;
begin
if var_a > var_b then
dbms_output.put_line(var_a);
else
dbms_output.put_line(var_b);
end if;
end;

  2)创建无参的存储过程

    

begin
getmax_zsm_00;
end;

 3.4 带参的存储过程

  3.4.1 使用的注意事项

    1)参数的数据类型不能包含长度或精度的修饰

    2)参数可以有多种模式,并且可以有默认值

        参数名 {in | out |in out} 类型 {:= | default}值

        参数模式:

          in    输入参数 负责向过程传入值              系统默认

          out          输出参数  负责传出值 实参必须是变量 不必赋值 在过程内必须赋值

          in out      输入输出参数    既负责传入又负责传出     实参是赋值后的变量在过程内可以赋值

        只有in模式的参数才可以有默认值

  3.4.2案例:

案例:创建一个带参的存储过程,传入两个数字,输出最大值
create or replace procedure getmax_zsm_00(
var_a in number:=10,var_b number)
is
begin
if var_a > var_b then
dbms_output.put_line(var_a);
else
dbms_output.put_line(var_b);
end if;
end;

  

  3.4.3带参的存储过程的调用 

declare
var_x number:=123;
var_y number:=12;
begin
getmax_zsm_00(1,10);
getmax_zsm_00(var_x,100);
getmax_zsm_00(var_x,var_y);
-- getmax_zsm_00(1);
end;

  3.4.4 参数赋值方式

   1) 按照位置赋值

   2)按照名字赋值             参数名=> 值

declare
var_x number:=123;
var_y number:=12;
begin
getmax_zsm_00(1,10);
getmax_zsm_00(var_x,100);
getmax_zsm_00(var_b=>10,var_a=>200);
getmax_zsm_00(var_b=>1);
end;

  3.4.5

3.4.5 练习:创建一个存储过程,传入两个数字,输出最大值,同时把两数之和保存在第二个变量,并测试
create or replace procedure getmax_zsm_00(
var_a in number,var_b in out number)
is
begin
if var_a > var_b then
dbms_output.put_line(var_a);
else
dbms_output.put_line(var_b);
end if;
var_b:=var_a + var_b;
end; -- 调用
declare
var_x number:=100;
begin
getmax_zsm_00(10,var_x);
dbms_output.put_line(var_x);
end;

  3.5 查看存储过程

    desc 过程名;

    desc user_source;

4.函数 Function

  4.1 plsql 中的函数和过程的区别

    1)关键字不同,过程是procedure  函数是 function

    2) 过程没有返回类型和返回值,函数有返回类型和返回值

    3)调用方式不同 ,过程在PLSQL中是直接调用,函数在PLSQL中需要组成表达式调用(使用变量接收返回值、作为函数或过程的参数)

  4.2语法

    create or replace function 函数名[参数列表]  return 数据类型

    is | as

      --  临时变量

    begin

      --  必须有return语句

    end;

  4.3 创建一个函数 ,传入两个数字,返回最小值

create or replace function getmin_zsm_00(
var_a number,var_b number) return number
is
begin
if var_a < var_b then
return var_a;
else
return var_b;
end if;
end; declare
var_x number:=100;
var_y number:=1;
var_result number;
begin
var_result:=getmin_zsm_00(var_x,var_y);
dbms_output.put_line(var_result);
dbms_output.put_line(getmin_zsm_00(123,10));
end;

5.包  package

    5.1概念

      把一组逻辑上相关的过程、函数、变量、类型等组织到一起的一种逻辑结构

    5.2 系统提供的包

      dbms_output:     输入输出包

      dbms_random:    随机包

      dbms_job:      定时任务调度包

      

查看包中的数据:
desc 包名;
desc dbms_random;
function value(low number,high number)
return number
包名.成员
select dbms_random.value(1,100) from dual; 5.3 自定义包
1)定义包 package -- 类似于C中.h文件
create [or replace] package 包名
is
-- 函数、过程的声明,类型的定义,变量的声明等
end[ 包名]; -- 定义一个包,包含一个过程和一个函数
create or replace package mypackage_zsm_00
is
procedure getmax(var_a number,var_b number);
function getmin(var_a number,var_b number)
return number;
end; 2) 定义包的主体(包的实现)
create [or replace] package body 包名
is
-- 函数、过程的实现
end[ 包名]; create or replace package body mypackage_zsm_00
is
procedure getmax(var_a number,var_b number)
is
begin
if var_a > var_b then
dbms_output.put_line(var_a);
else
dbms_output.put_line(var_b);
end if;
end; function getmin(var_a number,var_b number)
return number
is
begin
if var_a < var_b then
return var_a;
else
return var_b;
end if;
end;
end; -- 测试
declare
var_x number:=11;
var_y number:=1234;
var_res number;
begin
mypackage_zsm_00.getmax(var_x,var_y);
var_res:=mypackage_zsm_00.getmin(var_x,var_y);
dbms_output.put_line(var_res);
end;

6.触发器  trigger

  6.1概念

    触发器是一种特殊的‘存储过程’,它定义了一些和数据库相关事件(如insert、delete、update等)执行时应该执行的 ‘功能代码块’,通常用来管理

  复杂的完整性约束、或监控对表的修改,对数据审计功能

6.2 语法
create [or replace] trigger 触发器名
{before|after} {insert|update|delete}
on 表名 [for each row]
declare
begin
exception
end; 6.3 语句级触发器
emp_zsm_00 create or replace trigger tri_emp_zsm_00
before update on emp_zsm_00
declare
begin
dbms_output.put_line('table updated');
end; update emp_zsm_00 set salary=salary + 100
where id=1;
update emp_zsm_00 set salary=salary + 100
where id<1;
update emp_zsm_00 set salary=salary + 100
where id>1; 6.4 行级触发器
create or replace trigger tri_emp_zsm_00
before update on emp_zsm_00 for each row
declare
begin
dbms_output.put_line('table updated');
end; update emp_zsm_00 set salary=salary + 100
where id=1;
update emp_zsm_00 set salary=salary + 100
where id<1;
update emp_zsm_00 set salary=salary + 100
where id>1; 标识符:
:old 原值标识符
:new 新值标识符 表名%rowtype类型 insert :new
update :old :new
delete :old create or replace trigger tri_emp_zsm_00
before update on emp_zsm_00 for each row
declare
begin
dbms_output.put_line('table updated');
dbms_output.put_line('old:'||:old.id||','||:old.salary);
dbms_output.put_line('new:'||:new.id||','||:new.salary);
end; update emp_zsm_00 set salary=salary + 100
where id=1;
update emp_zsm_00 set salary=salary + 100
where id<1;
update emp_zsm_00 set salary=salary + 100
where id>1; 注意:触发器中不能包含任何有关事务的操作
事务 谁发起 谁结束 6.5 使用触发器产生主键的值
-- 创建一个表
create table testtrigger_zsm_00(
id number primary key,name varchar2(20));
-- 创建一个序列
create sequence trigger_id_zsm_00;
-- 创建触发器
create or replace trigger tri_pk_zsm_00
before insert on testtrigger_zsm_00 for each row
begin
select trigger_id_zsm_00.nextval into :new.id
from dual;
end; -- 插入一条语句
insert into testtrigger_zsm_00(name) values('test1');

  

练习:
1.使用游标 遍历s_dept表中的全部数据
2.创建一个存储过程,传入数字n(大于1的整数),计算1..n的累加和,保存在第二个参数,并测试。

Cursor、Exception、Procedure、Function、Package、Trigger(day06)的更多相关文章

  1. jsp内置对象之response、out、config、exception、pageContext。

    本文是对Jsp内置对象的response.out.config.exception.pageContext知识点的详细总结. response对象 Response内置对象和request内置对象是相 ...

  2. 原生JS:Function对象(apply、call、bind)详解

    Function对象(apply.call.bind) 原创文章,转摘请注明出处:苏福:http://www.cnblogs.com/susufufu/p/5850180.html 本文参考MDN做的 ...

  3. 004-For与Function进阶实战、Lazy的使用

    004-For与Function进阶实战.Lazy的使用 For进阶 非常常见的形式 可以加入条件表达式进行数据过滤 Function进阶 函数是有值的(默认的话为Unit),所以可以直接将结果赋值给 ...

  4. The use of function Merge (update、insert、delete)

    1.The use of function merge(update.insert.delete) Example: #1.Initialize the data create table #test ...

  5. Oracle: 禁忌给一般用户授权create any procedure、execute any procedure

    给一般用户授 create any procedure.execture any procedure 这2个权限是很不安全的事. 因为授权后,通过一些处理,该用户可以取得dba权限,请一定注意. 下面 ...

  6. js中使用function定义类、实例化,函数的调用方法

    function Test002(name, age){ name, age, this.printInfo = function(){ //定义的公有方法 console.log(name, age ...

  7. Java8 函数式接口 @FunctionalInterface以及常用Consumer<T>、Supplier<T>、Function<T, R>、Predicate<T>总结

    首先看看什么是Lambda 表达式 Lambda是一个匿名函数,我们可以把Lambda表达式理解为一段可以传递的代码(将代码像数据一样传递):最简单的Lambda表达式可由逗号分隔的参数列表.-> ...

  8. Function.prototype.bind、call与apply

    学习Function.prototype.bind.call与apply时,看到一篇博客,学到一些内容,但由于博客时间太久,根据官方文档对内容进行一些修正:下文为修正过内容 前言 前段时间面试遇见一题 ...

  9. 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入

    使用react全家桶制作博客后台管理系统   前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...

  10. jdk8系列三、jdk8之stream原理及流创建、排序、转换等处理

    一.为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX ...

随机推荐

  1. HDU 4542

    T_T终于让我过了,坑啊,竟然时限是200ms... 我是预处理出不整除了个数的,因为这个较容易一点.利用算术基本定理,f=p1^a1*p2^a2...... 所以,整除它的个数就是(a1+1)*(a ...

  2. Oracle学习(12):存储过程,函数和触发器

    存储过程和存储函数 l存储在数据库中供全部用户程序调用的子程序叫存储过程.存储函数. 注意:存储过程与存储函数声明变量时,用的是as   而不是declare 存储过程与存储函数差别 存储过程不带有返 ...

  3. 升级到VS2013常见问题

    问题1: Building an MFC project for a non-Unicode character set is deprecated 解决方法: 用于多字节字符编码 (MBCS) 的 ...

  4. .NET通用基本权限系统框架源代码

    DEMO下载地址: http://download.csdn.net/detail/shecixiong/5372895 一.开发技术:B/S(.NET C# ) 1.Windows XP以上 (支援 ...

  5. Python入门 六、像个 Pythonista

    pickle import pickle test_data = ['Save me!',123.456,True] f = file('test.data','w') pickle.dump(tes ...

  6. E20170826-hm

    squash   vt. 挤进; 将(某人[某物])压扁; 使沉默; 平定(叛乱等); meld vt. (使) 融合,合并,结合; n. 混合,合并; amend  vt. 修订; 改良,修改; a ...

  7. hdu5249

    这个是去年astar的题~ 标准做法主席树,然而渣渣并不会(我确实叫zhazha...), 所以,他先离线,离散化,然后树状数组+二分水过了.... 离线的目的主要是为了离散化,剩下的就和用一个树状数 ...

  8. thinkphp的session用法

    Session方法用于Session 设置.获取.删除和管理操作. Session 用于Session 设置.获取.删除和管理操作 用法 session($name, $value='') 参数 na ...

  9. prim解决最小生成树问题

    #include <iostream> #include <algorithm> #include <stdio.h> #include <math.h> ...

  10. Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C. Destroying Array -- 逆向思维

    原题中需要求解的是按照它给定的操作次序,即每次删掉一个数字求删掉后每个区间段的和的最大值是多少. 正面求解需要维护新形成的区间段,以及每段和,需要一些数据结构比如 map 和 set. map< ...