收藏 分享(赏)

PLSQL.ppt

上传人:myw993772 文档编号:7360253 上传时间:2019-05-16 格式:PPT 页数:236 大小:1.06MB
下载 相关 举报
PLSQL.ppt_第1页
第1页 / 共236页
PLSQL.ppt_第2页
第2页 / 共236页
PLSQL.ppt_第3页
第3页 / 共236页
PLSQL.ppt_第4页
第4页 / 共236页
PLSQL.ppt_第5页
第5页 / 共236页
点击查看更多>>
资源描述

1、PL/SQL语言 -过程化SQL语言,本章内容,PL/SQL概述 PL/SQL基础 控制结构 游标 异常处理 存储子程序 包 触发器,PL/SQL概述,PL/SQL特点PL/SQL执行过程PL/SQL开发工具,PL/SQL简介,PL/SQL是一种过程语言,是ANSI标准SQL的ORACLE版的扩充,是一个完全可移植的、高性能的事务处理语言。PL/SQL允许使用过程化的方法如循环、分支等程序块来处理数据,不但能像第三代语言一样,可以一步一步地定义下一步做什么,而且将DB技术和过程化程序设计语言结合起来,将SQL的数据操纵功能与过程语言数据处理功能结合起来,因而将强大的程序设计能力带入到ORACL

2、E DB 及其应用开发工具中。 PL/SQL不是用来编写面向用户界面的程序,它的输入、输出面向数据库。用PL/SQL编写的主要是服务器端的程序。 PL/SQL是ORACLE的核心编程语言,用于存储过程、触发器、包、以及前端开发工具的事件处理程序等。,PL/SQL简介,PL/SQL很容易学习和使用。只要有中等编程背景的专业人员就可以很快掌握并用 PL/SQL语法不太费劲地开发出相当复杂的程序。没有编程背景的专业人员学习 PL/SQL时可以把更多精力放在基本结构上,如变量声明、条件语句处理,等等。 PL/SQL与ORACLE数据库密切集成。对 ORACLE数据库中的数据进行 S Q L操作时不需要

3、任何特殊的命令语法。 PL/SQL特别适合处理大块数据。 Oracle PL/SQL提供的cursor for循环是个特殊结构,可以查询多个表数据行,然后以迭代方式处理每一行数据。这个特性可以批量处理大量数据。 PL/SQL支持命名与匿名程序。可以用 PL/SQL开发多种不同的命名程序,包括存储过程、函数和包。这些代码块在数据库中实际编译和存储,以便今后使用。也可以编写匿名程序,在提交执行代码时编译、执行,而不在数据库中实际存储。,PL/SQL特点,与SQL语言紧密集成。在PL/SQL块中使用SQL的所有数据操纵命令和事务控制命令(不支持数据定义命令),支持全部的SQL函数和运算符 以块为单位

4、,减小网络流量,执行效率高,提高应用程序的运行性能。 模块化的程序设计功能,提高了系统可靠性。 服务器端程序设计,可移植性好。 与数据库的数据类型相集成PL/SQL支持SQL全部数据类型,增加%type、%Rowtype,更好地将PL/SQL与DB数据类型结合起来,PL/SQL执行过程与开发工具,PL/SQL块,SQL语句,客户端应用程序,PL/SQL引擎,数据库服务器,过程化语句执行器,SQL执行器,块中SQL语句,PL/SQL执行过程,PL/SQL开发工具,SQL *PLUS Procedure Builder Oracle Form、Oracle Reports PL/SQL Devel

5、oper,PL/SQL基础,PL/SQL程序结构 数据类型 变量与常量 PL/SQL中的SQL语句,PL/SQL块分类,匿名块 命名块 函数 存储过程 包 触发器,PL/SQL块的组成,一个基本的PL/SQL块有三部分组成: DECLARE说明部分 BEGIN可执行部分(程序主体) EXCEPTION异常处理部分 END; /,PL/SQL块的组成,定义部分(DECLARE)PL/SQL块中所有的常量、变量、游标等标识符的定义必须集中在以DECLARE关键字开头的定义部分可执行部分(BEGIN)该部分中包括实际的对数据库的操作语句以及PL/SQL的各种控制语句,是必不可少的。异常处理部分(EX

6、CEPTION)当程序发生错误时,使用该部分对错误进行处理,说明,执行部分是必需的,而声明部分和异常部分是可选的; 可以在一个块的执行部分或异常处理部分嵌套其他的PL/SQL块; 所有的PL/SQL块都是以“END;”结束,PL/SQL基础,3. 定义部分定义常量或变量 标识符 constant 数据类型 not null :=默认值或PL/SQL表达式 注: 如果加上关键字constant,则表示所定义的是一个常量,必须为它赋初值,在程序中只能引用而不能再改变其值。 每行只能定义一个标识符,必须以字母开头,不分大小写。 如果定义的标识符不能为空,则加上关键字NOT NULL,并赋初值。 为标

7、识符赋值,使用赋值操作符“:=” 。- (equal to )变量声明分为标量型变量和组合型变量声明,PL/SQL基础,标量型变量 所谓标量型变量是指其内部没有成员的变量。常见的标量型数据类型有如下几种:number 数字型 char 字符型date 日期型 long 长型boolean 布尔型,仅有3个取值:true,false,nullvarchar2 可变长字符型如:声明一个日期型变量today,其初始值为系统当前日期today date not null:=sysdate;Age number(3) not null:=25;Pi constant number(9) :=3.1415

8、926;Sex boolean:=true;,PL/SQL基础,如果希望一个变量的类型与某个变量或数据库基表中某个列的数据类型一致,而又不知道该变量或列的数据类型,这时必须使用%type例:声明一个变量Student_name,其类型基于另一个变量Teacher_nameDECLARETeacher_name char(10);Student_name Teacher_name%type;BEGIN,PL/SQL基础,例:声明一个变量no,使其与表emp中empno的类型一致DECLARENo emp.empno%typeBEGIN 好处: 即使不清楚emp表的列定义,也可以保证两者定义的一致

9、性。 如果改变了emp表的empno列定义,如由char(6)改为char(8),不需要修改pl/sql程序中no变量的定义,PL/SQL基础,字符串比较 填充比较:通过在短字符串后添加空格,使两个字符串达到相同长度,然后根据每个字符的ASCII码进行比较。 非填充比较:根据每个字符的ASCII码进行比较,最先结束的字符串为小。 PL/SQL中规定: 对定长的字符串(CHAR类型的字符串和字符串常量)采用填充比较 如果比较的字符串中有一个是变长字符串(VARCHAR2类型的字符串),则采用非填充比较。,PL/SQL基础,组合型变量 组合型变量内部包含若干个成员,每个成员由标量型变量组成。其语法

10、格式如下TYPE IS RECORD OF( | NOT NULL, | NOT NULL,);其中: PL/SQL RECORD 中域的名称域的数据类型域的RECORD类型名RECORD类型名,PL/SQL基础,例:定义一个变量,存放一个学生的有关信息DECLAREtype student is record of (id number(4) not null,name char(10) not null,sex Boolean not null,birthdate date,physics number(3),chemistry number(3);S STUDENT 注:记录可以定义不同

11、的域存放不同的数据。如果需要声明一个记录类型变量(S),首先要定义一个记录类型(STUDENT)然后在声明该记录类型变量。,PL/SQL基础,如果在声明一个组合型变量时,其数据类型和基表的数据结构一致,则可以使用%ROWTYPE的形式 例:声明一个变量,其结构与表emp的数据结构相一致DECLAREemp_value emp%rowtypeBEGIN,PL/SQL基础,有关%TYPE 和%ROWTYPE%TYPE 特别是%ROWTYPE,是准确定义变量的非常好的特性工具。在做PL/SQL程序时,最经常犯的错误就是将内部变量定义的与DB表相应字段的类型或长度不一样,在程序中进行值的比较时,就会出

12、错。如:VARCHAR2数据不会与CHAR数据进行正常的比较。另外,把较大的数据放到一个较小的变量中时,这个错误会引起应用终止。 %TYPE和%ROWTYPE消灭了这类问题, 此外, %ROWTYPE还节省了手工输入变量定义的工作。,变量的作用域,变量的作用域是指变量的有效作用范围,从变量声明开始,直到块结束。 如果PL/SQL块相互嵌套,则在内部块中声明的变量是局部的,只能在内部块中引用,而在外部块中声明的变量是全局的,既可以在外部块中引用,也可以在内部块中引用。 若不在子块中重新定义,则在主块中定义的变量作用于所有子块 如果内部块与外部块中定义了同名变量,则在内部块中引用外部块的全局变量时

13、需要使用外部块名进行标识。,PL/SQL基础,如: DECLAREerr char(80)BEGIN 子块1 -块标号DECLAREv1 number(4)BEGINselect empno into v1 from emp wherejob=presidentEND one; 子块2 DECLAREv1 number(4)BEGINselect empno into v1 from emp wherejob=managerEND two;END;/, DECLAREv_ename CHAR(15);v_outer NUMBER(5); BEGINv_outer :=10;DECLAREv_e

14、name CHAR(20); v_inner DATE;BEGINv_inner:=sysdate;v_ename:=INNER V_ENAME;OUTER.v_ename:=OUTER V_ENAME;END;DBMS_OUTPUT.PUT_LINE(v_ename); END;,PL/SQL基础,4. 可执行部分PL/SQL的可执行部分包括变量赋值语句、select、insert、update、delete、commit、rollback等数据查询、数据操纵或事物控制命令;但不能使用create、alter、drop、grant、revoke等数据定义或控制命令。标量型变量赋值使用“:=”

15、,PL/SQL RECORD类型变量赋值,采用“:=”如:teacher_name:=LIU;student.name:=FAN; student.sex:=true; student.physics:=90;,PL/SQL基础,对%rowtype型变量的赋值可以使用与RECORD类型变量相同的方法,也可以使用select语句如:select * into emp_value from emp where ename:=FAN;例题:计算表emp中所有雇员的平均工资SQL DECLAREavg_sal number(7,2);BEGINselect avg(sal) into avg_sal

16、from emp;END;/,PL/SQL基础,select语句必须与into子句相配合, INTO句子后的变量用于接收查询的结果,变量的个数、顺序应该与查询的目标数据相匹配,也可以是记录类型的变量。SELECTINTO语句只能查询一个记录的信息,如果没有查询到任何数据,则会产生NO_DATA_FOUND异常;如果查询到多个记录,则会产生TOO_MANY_ROW异常。 如果要执行一个PL/SQL块,必须在关键字END后加上“/”,并按回车. 在PL/SQL中,SQL语句的语法和交互命令时是一样的。,PL/SQL基础,给变量赋值: 变量名:=表达式使用select语句select 列名 into

17、 变量名 from基表名 变量给字段赋值: 插入赋值 insert into 基表名values(表达式1, 表达式2,)更新赋值-update基表名set 列名=表达式SQLupdate empset sal=sal+300Where ename=FAN and deptno=10;,PL/SQL中DML语句对标准SQL语句中的DML语句进行了扩展,允许使用变量。示例 DECLAREv_empno emp.empno%TYPE :=7500; BEGININSERT INTO emp(empno,ename,sal,deptno) VALUES(v_empno,JOAN,2300,20);U

18、PDATE emp SET sal=sal+100 WHERE empno=v_empno;DELETE FROM emp WHERE empno=v_empno; END;,PL/SQL基础,6. SQL与PL/SQL (1)插入数据:例declareMy_sal number(7,2):=3040.45;My_ename char(9):=WANDA;My_hiredate date:=08-11月-2002;BeginInsert into emp(empno,ename,job,sal)Values(2222,my_ename,drive,my_sal);End; / 若my_enam

19、e为char(25),结果会如何?Varchar(30)呢?,PL/SQL基础,6. SQL与PL/SQL (2)删除:例Declaremy_ename char(9):=WANDA;BeginDelete from empWhere ename=my_ename;End;/,PL/SQL基础,6. SQL与PL/SQL (3)函数:例DeclareMy_ename varchar2(25):=WANDA;beginInsert into emp(empno,ename)Values(2222,upper(my_ename);End;/,PL/SQL基础,7. PL/SQL中的信息输出SQL

20、set serveroutput on-环境设置SQL begindbms_output.put_line(要输出的信息);end; / 注:执行PL/SQL时,在显示PL/SQL PROCEDURE SUCCESSFULLY COMPLETED之前没有任何输出。输出语句帮助我们跟踪程序的逻辑流程。,PL/SQL基础,8.空操作问题 NULL语句不作任何操作,只是将控制转移到下一条语句。有的地方必须要有子句,而又不希望作任何操作时,NULL语句很有用。 例: When zero_devide then Rollback; When others then Null; End;,PL/SQL基础

21、,RETURNING如果要查询当前DML语句操作的记录的信息,可以在DML语句末尾使用RETURNING语句返回该记录的信息。 DECLAREv_sal emp.sal%TYPE; BEGINUPDATE emp SET sal=sal+100 WHERE empno=7844 RETURNING sal INTO v_sal;DBMS_OUTPUT.PUT_LINE(v_sal); END;,控制结构,选择结构 循环结构 跳转结构,条件控制,IF_THEN_ELSE语句 语法格式: IF THENELSEEND IF; 功能: 如果条件成立,将执行,否则执行,执行完后,转到下一条语句执行。

22、说明: 是一个布尔型变量或表达式,取值只能是TRUE,FALSE,NULL。,执行流程,语句组1,语句组2,条件,true,false,条件控制,If-then-else结构的几个规则: 一个if语句只能包含一个else语句 else后面不加分号 任何时候if 条件表达式后面都要跟随then语句 结构终止于end if 在then或else部分可嵌套一个或多个If-then-else语句 例: 决定当前月份是否是二月且这一月的最后一天的日期是什么,条件控制,Declare aa number remainder number;month char(3);last_day char(2); Be

23、ginmonth:=substr(to_char(sysdate,DD-MON-YY),4,3);if (month=FEB) thenaa= to_number(substr(to_char(sysdate,DD-MON-YY),8,2);remainder:=mod(aa,4);if (remainder=0) then last_day:=29;dbms_output.put_line(This is a leap year);dbms_output.put_line(last Day is the|last_day|th);else,条件控制,last_day:=28;dbms_out

24、put.put_line(This is not a leap year);dbms_output.put_line(last Day is the|last_day|th);end if;Else dbms_output.put_line(The month is not February);end if; End; /,条件控制,IF_THEN_ELSIF语句 语法格式: IF THENELSIF THENELSIF THEN END IF; 功能:如果成立,将执行;否则判断,如果成立执行;否则,判断,如此循环,直到判断,如果都不成立,则执行执行,执行完后,转到下一条语句执行 。,执行流程

25、,语句组1,语句组2,true,false,false,语句组n,语句组n+1,false,true,true,PL/SQL流程控制,例题:据表EMP中DEPTNO的值,为姓名为FAN的雇员修改工资:部门号为10,加$100;20,加$200;30,加$300;否则加$400。 DECLARENAME EMP.ENAME%TYPE:=FAN;INCREMENT EMP.SAL%TYPE;FANDEPT EMP.DEPTNO%TYPE; BEGINSELECT DEPTNO INTO FANDEPT FROM EMP WHERE ENAME=NAME; IF FANDEPT=10 THEN IN

26、CREMENT:=100; ELSIF FANDEPT=20 THEN INCREMENT:=200; ELSIF FANDEPT=20 THEN INCREMENT:=300; ELSE INCREMENT:=400; END IF; UPDATE EMP SET SAL=SAL+INCREMENT WHERE ENAME=FAN;COMMIT; END;/,PL/SQL流程控制,说明: ELSIF不要误写为ELSEIF If-then-elsif适用于需要对大量的条件进行判断时 每一个条件都是相互排斥的 任意一条件满足,程序执行该条件后的命令,然后推出该结构。,搜索式CASE语句,基本语法

27、 CASEWHEN condition1 THEN statements1;WHEN condition2 THEN statements2;WHEN conditionn THEN statementsn;ELSE else_statements; END CASE;,等值比较的CASE语句,基本语法 CASE test_valueWHEN value1 THEN statements1;WHEN value2 THEN statements2;WHEN valuen THEN statementsn;ELSE else_ statements; END CASE;,DECLAREv_dep

28、tno emp.deptno%type;v_increment NUMBER(4);v_empno emp.empno%type; BEGINv_empno:=,搜索式CASE语句,根据输入的员工号,修改该员工工资。如果该员工工资低于1000,则工资增加200;如果工资在1000-2000之间,则增加150;如果工资在2000-3000之间,则增加100;否则增加50。,DECLARE v_sal emp.sal%type; v_increment NUMBER(4); v_empno emp.empno%type; BEGIN v_empno:=,循环结构,UNTIL循环 WHILE循环 F

29、OR循环,PL/SQL流程控制,2. 循环控制语句FOR循环:FOR循环一般用于已知循环次数的循环 FOR 计数器 IN REVERSE 下界上界 LOOP语句1;语句2; 循环体 END LOOP;,PL/SQL流程控制,注:计数器是用于记录循环次数的变量,它不需显示的在变量定义部分进行定义,系统视其为整型变量系统默认计数器从下界往上界递增记数,加上REVERSE表示计数器从上界到下界递减记数计数器变量只能在循环体内部使用,不能在循环体外部使用 例:,PL/SQL流程控制,例1:输出1-5的阶乘 SQL Declarexx number(3):=1;num number(3):=5;Begi

30、nIf num0 thenFor I in 1numLoopXx:=xx*I; Dbms_output.put_line(xx);End loop;End if; End; /,PL/SQL流程控制,执行CREATE TABLE temp_table(num_col NUMBER,info_col CHAR(10) 语句创建temp_table表, 利用FOR循环向temp_table表中插入50条记录。BEGINFOR v_counter IN 150 LOOPINSERT INTO temp_table VALUES (v_counter, Loop Index);END LOOP; EN

31、D;,PL/SQL流程控制,直到型循环:先执行循环体,后判断条件,循环体至少要执行一次LOOPEXIT WHEN 条件END LOOP;,PL/SQL基础,如:计算1100所有整数的和 SQLset serveroutput on; SQLDeclare I number(3):=100; X number(4):=0; Begin Loop X:=x+I; I:=I-1; Exit when I=0;-中止循环条件,否则,无限循环 End loop; Dbms_output.put_line(x); End;,利用直到循环向temp_table表中插入50条记录。DECLAREv_count

32、er BINARY_INTEGER := 1; BEGINLOOPINSERT INTO temp_table VALUES (v_Counter, Loop index);v_counter := v_counter + 1;EXIT WHEN v_counter 50;END LOOP; END;,PL/SQL流程控制,当型循环:先判断条件,后执行循环体,循环体可能一次也不执行WHILE LOOPEND LOOP;,利用WHILE循环向temp_table表中插入50条记录。程序为: DECLAREv_counter BINARY_INTEGER :=1; BEGINWHILE v_cou

33、nter = 50 LOOPINSERT INTO temp_table VALUES (v_counter, Loop index);v_counter := v_counter + 1;END LOOP; END;,PL/SQL流程控制,循环的嵌套:同种及不同的循环控制语句均可实现嵌套 WHILE LOOPWHILE LOOPEND LOOP;END LOOP;,PL/SQL流程控制, LOOPWHILE LOOPEND LOOPEXIT WHEN 条件2END LOOP;,PL/SQL流程控制, FOR 计数器 IN REVERSE 下界上界LOOPWHILE LOOPEND LOOPE

34、ND LOOP; 循环的嵌套 三种基本的循环语句可以进行嵌套 一个循环可以作为一个普通的语句,完全地嵌套到另一个循环之中。 嵌套的时候,一个循环必须完整的嵌套在另一个循环里,否则是错误的。,PL/SQL流程控制,例题:求100-150的所有素数,并插入到表PRIME中。算法把m的平方根赋值给变量k,让m被2到k除,如果m能被2到k之中任何一个整数整除,则令I等于0,并提前退出循环;否则,完成最后一次循环后I仍然大于0,表明m是一个素数,计数器n加1。 declarem number(3):=101;i number(2);k number(3);n number(2):=0;beginwhil

35、e m150loopk:=round(sqrt(m),0);i:=2;,PL/SQL流程控制,loopif mod(m,i)=0 theni:=0;exit;end if;i:=i+1;exit when ik;end loop;if i0 thenn:=n+1;insert into prime(no,prime) values(n,m);end if;m:=m+2;end loop;end;/select * from prime,PL/SQL流程控制,3. 跳转语句标号GOTO 标号; 注:在进行PL/SQL编程时,应尽量避免使用GOTO语句,滥用GOTO语句会使程序流程无规律、可读性差

36、 注意事项: 标号可以放在块的任何地方。 可以实现同一块中语句之间的跳转。 可从子块跳至父块,不能从父块跳至子块。 不能从if语句体外跳入if语句体内。 不能从循环体外跳入循环体内。,PL/SQL流程控制,3. 跳转语句采用goto语句求1100的和declarei number(3):=100;begin:sum:=0;:sum:=:sum+i;i:=i-1;if i0 then goto label;end if;end;,DECLAREv_counter BINARY_INTEGER :=1; BEGININSERT INTO temp_table VALUES (v_counter,

37、Loop index);v_counter := v_Counter + 1;IF v_counter=50 THENGOTO LABEL;END IF; END;,游标的使用,游标的概念:是Oracle系统在内存中开辟的一个工作区,其中存放select语句的查询结果,该结果既可以是零条记录、单条记录,也可以是多条记录。在游标所定义的工作区中,存在着一个指针(POINTER),在初始状态它指向查询结果的首记录。我们可以通过执行FETCH语句,使指针逐行下移。游标分为两种类型: 显式游标:明确定义的游标,解决程序中返回多行的问题。 隐式游标(系统预定义游标):SQL命令中用到的,没有明确定义的游

38、标。存储有关最新一条SQL命令的处理信息。调用格式为SQL%。 对显式游标的操作包括:定义游标、打开游标、提取数据、以及关闭游标。,定义游标,语法格式 CURSOR cursor_name IS select_statement ; 说明 游标必须在PL/SQL块的声明部分进行定义; 游标定义时可以引用PL/SQL变量,但变量必须在游标定义之前定义; 定义游标时并没有生成数据,只是将定义信息保存到数据字典中; 游标名仅是标示符,不能给其赋值,不能在等式中出现。 游标定义后,可以使用cursor_name%ROWTYPE定义游标类型变量。,打开游标,语法格式 OPEN cursor_name;

39、说明 检查变量的值 执行游标定义时对应的SELECT语句,将查询结果检索到工作区中。 游标指针指向第一个元组 一旦游标打开,就无法再次打开,除非先关闭 如果游标定义中的变量值发生变化,则只能在下次打开游标时才起作用。,游标的使用,4. 提取数据语法格式:FETCH 游标名 INTO 变量1,变量2,工作区内的游标指针只能向下移动,不能回退。如果查询完第二条记录后又想回退到第一条记录,则必须关闭游标后重新打开游标。在使用FETCH语句之前必须先打开游标,这样才能保证工作区内有数据INTO子句中的变量个数、顺序、类型必须与工作区中每行记录的字段数、顺序及数据类型一一对应,关闭游标,语法格式CLOS

40、E cursor_name; 说明 游标所对应的内存工作区变为无效,释放与游标相关的系统资源。,例题,修改表EMP中各个雇员的工资:部门号为10,加$100;20,加$200;30,加$300。 DECLARErow emp%rowtype;increment number(4);CURSOR cursor_emp IS SELECT * FROM EMP;I number(2); BEGINselect count(*) into I from emp;open cursor_emp;FETCH cursor_emp INTO ROW;,例题,If row.deptno=10Then inc

41、rement:=100; Elsif row.deptno=20Then increment:=20; Elseincrement:=300; End if;Update emp set sal=sal+increment where ename=row.ename;I:=I-1;IF I0 THEN GOTO LABEL;ENDIF; CLOSE cursor_emp; end; /,根据输入的部门号查询某个部门的员工信息,部门号在程序运行时指定。 DECLAREv_deptno emp.deptno%TYPE;CURSOR c_emp IS SELECT * FROM emp WHERE

42、deptno=v_deptno;v_emp c_emp%ROWTYPE; BEGINv_deptno:=,游标的属性,5. 游标的属性无论是显式游标还是隐式游标,每一个游标都有四种属性,利用它们可以存取有关语句执行的信息。%ISOPEN:该属性是布尔型,描述游标是否打开%FOUND:该属性是布尔型,如果最近一次FETCH操作返回有结果或刚执行的一条DML语句处理了记录,则为TRUE,反之则为FALSE%NOTFOUND:该属性是布尔型,如果最近一次FETCH操作没有返回结果则为TRUE,反之则为FALSE%ROWCOUNT:该属性是数字型,描述到目前为止实际从游标工作区抽取的记录数 注:游标属

43、性只能在pl/sql块中使用,而不能在sql命令中使用。,显式游标的检索,利用简单循环检索游标 利用WHILE循环检索游标 利用FOR循环检索游标 利用GOTO循环检索游标,游标的属性,修改表EMP中各个雇员的工资:部门号为10,加$100;20,加$200;30,加$300。 DECLARErow emp%rowtype;increment number(4);CURSOR cursor_emp IS SELECT * FROM EMP;I number(2); BEGINif not cursor_emp%isopen then;open cursor_emp;end if;FETCH c

44、ursor_emp INTO ROW;,游标的属性,If row.deptno=10Then increment:=100; Elsif row.deptno=20Then increment:=20; Elseincrement:=300; End if;Update emp set sal=sal+increment where ename=row.ename;IF cursor_emp%FOUND THEN GOTO LABEL;ENDIF; CLOSE cursor_emp; end; /,利用简单循环检索游标,DECLARECURSOR cursor_name IS SELECT;

45、BEGINOPEN cursor_name;LOOPFETCHINTO;EXIT WHEN cursor_name%NOTFOUND;END LOOP;CLOSE cursor_name; END;,利用简单循环统计并输出各个部门的平均工资。 DECLARECURSOR c_dept_stat IS SELECT deptno,avg(sal) avgsal FROM emp GROUP BY deptno;v_dept c_dept_stat%ROWTYPE; BEGIN OPEN c_dept_stat; LOOPFETCH c_dept_stat INTO v_dept;EXIT WHE

46、N c_dept_stat%NOTFOUND;DBMS_OUTPUT.PUT_LINE(v_dept.deptno| |v_dept.avgsal);END LOOP;CLOSE c_dept_stat; END;,游标的属性,例:处理具有最高薪水的5名职员的信息SET SERVEROUTPUT ON;DECLAREcursor c1 is select ename,job from emporder by sal desc;my_ename emp.ename%type;my_job emp.job%type;BEGINopen c1;LOOPfetch c1 into my_ename,m

47、y_job;dbms_output.put_line(my_ename | | my_job);EXIT when (c1%notfound) or (c1%rowcount5);END LOOP;close c1;END;,利用WHILE循环检索游标,DECLARECURSOR cursor_name IS SELECT; BEGINOPEN cursor_name;FETCHINTO;WHILE cursor_name%FOUND LOOPFETCHINTO;END LOOP;CLOSE cursor; END;,利用WHILE循环统计并输出各个部门的平均工资。 DECLARECURSOR

48、 c_dept_stat IS SELECT deptno,avg(sal) avgsal FROM emp GROUP BY deptno;v_dept c_dept_stat%ROWTYPE; BEGINOPEN c_dept_stat;FETCH c_dept_stat INTO v_dept; WHILE c_dept_stat%FOUND LOOPDBMS_OUTPUT.PUT_LINE(v_dept.deptno| |v_dept.avgsal);FETCH c_dept_stat INTO v_dept;END LOOP;CLOSE c_dept_stat; END;,游标的属性

49、,%found 与%notfound 在while循环中的使用: Declare name emp%ename;cursor a is select ename from emp; Beginopen afetch a into name;while a%found loopdbms_output.put_line(name); End loop; Close a; End; /,带参数游标的使用,为使光标的适用性更强,PL/SQL支持带参数的光标。 语法格式如下: DECLARECURSOR 游标名 (形式参数1 数据类型,形参2 数据类型)IS SELECT 语句; 在打开光标时,为形参赋值。如: DECLARECURSOR C1 (m_ename char1,m_sal number) is select open c1(marry,300) 定义游标时,只能指定参数的类型,而不能指定参数的长度、精度、刻度; 打开带参数的游标时,实参的个数和数据类型等必须与游标定义时形参个数和数据类型等相匹配。,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报