[VIP专享]第4章 PLSQL语言基础(理论)01修改后
- 格式:pdf
- 大小:753.78 KB
- 文档页数:31
PLSQL循序渐进全面学习教程(全)PL/SQL是用于Oracle数据库的编程语言,它结合了SQL语句的数据操作能力和一般编程语言的逻辑控制能力。
PL/SQL循序渐进的全面学习教程将帮助你逐步学习和掌握PL/SQL的各个方面。
1.简介和基础知识:-PL/SQL的概念和背景-PL/SQL的开发工具和环境-PL/SQL和SQL的关系-PL/SQL的基本语法和数据类型2.变量和常量:-PL/SQL变量的声明和使用-不同类型的变量和数据类型-常量的定义和使用3.控制结构:-IF-THEN语句和IF-THEN-ELSE语句-CASE语句的使用-循环语句(FOR循环、WHILE循环)4.异常处理:-异常的概念和分类-异常处理的方法和语句-自定义异常和错误处理5.子程序和函数:-PL/SQL子程序和函数的概念和用途-创建和调用子程序和函数-参数传递和返回值6.游标和结果集:-游标的概念和使用场景-游标的声明、打开、关闭和绑定-使用游标处理结果集和数据集7.触发器:-触发器的概念和作用-创建和使用触发器-触发器的触发事件和触发时机8.包和包体:-包和包体的定义和特点-创建和使用包和包体-包的封装和共享9.过程和函数:-过程和函数的概念和区别-创建和使用过程和函数-过程和函数的编写和调用10.使用PL/SQL开发应用程序:-使用PL/SQL编写数据库操作代码-使用PL/SQL开发业务逻辑-PL/SQL和其他编程语言的集成以上是PL/SQL循序渐进全面学习教程的大纲,你可以根据自己的学习进度逐步深入学习每个主题。
希望这个教程对你学习和掌握PL/SQL编程语言有所帮助!。
PLSQL基本语法作者:gqk:1,什么是plsql: 是专⽤于Oracle服务器,在SQL基础之上,添加了⼀些过程化控制语句,叫PLSQL过程化包括有:类型定义,判断,循环,游标,异常或例外处理。
PLSQL强调过程2,Plsql语句块: PL/SQL程序都是以块(block)为基本单位,整个PL/SQL块分三部分:声明部分(⽤declare开头)执⾏部分(以 begin开头)其中执⾏部分是必须的,其他两个部分可选部分(以exception开头)结束:end--基本输出语句:BEGINdbms_output.put_line('hello,world');END;--基本输出语句BEGINdbms_output.put_line('hello,world');dbms_output.put_line(157);dbms_output.put_line(sysdate);dbms_output.put_line(true);--不能传⼊布尔值END;3,Plsql语句块分类: 匿名块:动态构造只执⾏⼀次(main)⼦程序:存储在数据库中的存储过程,函数及包等。
当在数据库建⽴好后可以在其他⼦程序中调⽤触发器:当数据库发⽣操作时,会触发⼀些事件,从⽽⾃动执⾏相应的程序4,Plsql中的变量类型:5,变量的使⽤: plsql中声明和执⾏部分要严格分开,在java中时先声明后写变量plsql中相反先声明在写数据类型: 变量在声明后没有赋值输出结果为空: 变量的声明和初始化:(boolean中只能声明不能输出)DECLAREi NUMBER(4) := 157;j NUMBER(6);c VARCHAR2(200) := 'HELLO,WORLD';d DATE := sysdate;b BOOLEAN := TRUE;BEGINj := 1000;--只能写在执⾏部分dbms_output.put_line('i=' || i);dbms_output.put_line('j=' || j);dbms_output.put_line('c=' || c);dbms_output.put_line('d=' || d);END;在声明快中对常量的声明: 变量名称【constant】 type 【not null】【:value】DECLAREc CONSTANT NUMBER(4) := 100;c2 NUMBER(4) NOT NULL := 101;BEGIN--c := 101; --常量不能重复赋值dbms_output.put_line('c=' || c);dbms_output.put_line('c2=' || c2);END; --空语句 NULL 执⾏语句中必须写东西DECLAREc CONSTANT NUMBER(4) := 100;c2 NUMBER(4) NOT NULL := 101;BEGINNULL;--空语句,作为占位符使⽤END; 6,PLSQL中使⽤sql: --更新100员⼯,⼯资增加1块钱 :(不能再执⾏块中直接输出select语句)声明变量:员⼯的编号声明变量:⼯资追加的钱数DECLAREv_empid BINARY_INTEGER := 100;v_money BINARY_INTEGER := 1;BEGINUPDATE employees SET salary=salary+v_moneyWHERE employee_id=v_empid;COMMIT;END;PLSQL中使⽤SQL语句的⼏种情况:DML或DCL语句:直接执⾏ 查询语句:SELECT...INTO 或者游标DDL语句:动态SQL执⾏ 7,SELECT...INTO...的使⽤:语法:SELECT 列1,列2,…… INTO 变量1,变量2,……--查询某个员⼯编号的姓名和⼯资:员⼯编号姓名⼯资 列和变量的顺序,个数必须保持⼀致(如果没有数据则会抛出异常,返回的结果超过⼀⾏也会有异常)DECLAREv_empid BINARY_INTEGER := 101;v_name VARCHAR2(50);v_salary NUMBER(8,2);BEGINSELECT last_name,salaryINTO v_name,v_salaryFROM employeesWHERE employee_id=v_empid;dbms_output.put_line(v_empid || ',' || v_name || ',' || v_salary);END;--查询某个员⼯编号的姓名,⼯资,⼊职⽇期,部门编号:(以上思路我们需要声明多个变量) DECLAREv_empid BINARY_INTEGER := 101;v_name VARCHAR2(50);v_salary NUMBER(8,2);v_hiredate DATE;v_deptid BINARY_INTEGER;BEGINSELECT last_name,salary,hire_date,department_idINTO v_name,v_salary,v_hiredate,v_deptidFROM employeesWHERE employee_id=v_empid;dbms_output.put_line(v_empid || ',' || v_name || ','|| v_salary || ',' || v_hiredate || ',' || v_deptid);END;java中处理多个数据我们可以封装为对象:plsql中可以声明记录类型:时把逻辑相关的数据作为⼀个单元存储起来:--记录类型record--查询某个员⼯编号的姓名,⼯资,⼊职⽇期,部门编号DECLARETYPE emp_record_type IS RECORD (empid BINARY_INTEGER := 102,ename VARCHAR2(50),salary NUMBER(8,2),hiredate DATE,deptid BINARY_INTEGER);e emp_record_type;BEGINSELECT employee_id,last_name,salary,hire_date,department_idINTO eFROM employeesWHERE employee_id=e.empid;dbms_output.put_line(e.empid);dbms_output.put_line(e.ename);dbms_output.put_line(e.salary);dbms_output.put_line(e.hiredate);dbms_output.put_line(e.deptid);END; --参照引⽤类型:参照已有的数据类型--参照引⽤类型--参照引⽤变量类型:变量名称%TYPE--参照引⽤表中的列类型:表名.列名%TYPE--参照引⽤表的记录类型:表名%ROWTYPE demo:DECLAREi NUMBER(4);j i%TYPE := 100;--参照i的类型k employees.employee_id%TYPE := 101;--参照员⼯表中员⼯编号的数据类型BEGINdbms_output.put_line('j=' || j);dbms_output.put_line('k=' || k);END;--查询某个员⼯编号的姓名,⼯资,⼊职⽇期,部门编号(参照类型)DECLARETYPE emp_record_type IS RECORD (empid employees.employee_id%TYPE := 102,ename st_name%TYPE,salary employees.salary%TYPE,hiredate employees.hire_date%TYPE,deptid employees.department_id%TYPE);e emp_record_type;BEGINSELECT employee_id,last_name,salary,hire_date,department_idINTO eFROM employeesWHERE employee_id=e.empid;dbms_output.put_line(e.empid);dbms_output.put_line(e.ename);dbms_output.put_line(e.salary);dbms_output.put_line(e.hiredate);dbms_output.put_line(e.deptid);END; --查询某个员⼯编号的姓名,⼯资,⼊职⽇期,部门编号(参照引⽤表的记录类型)DECLAREe employees%ROWTYPE;BEGINe.employee_id := 103;SELECT *INTO eFROM employeesWHERE employee_id=e.employee_id;dbms_output.put_line(e.employee_id);dbms_output.put_line(st_name);dbms_output.put_line(e.salary);dbms_output.put_line(to_char(e.hire_date,'yyyy-mm-dd'));dbms_output.put_line(e.department_id);END;--PLSQL表类型 /*TYPE ⾃定义类型名称 IS TABLE OF 元素类型INDEX BY BINARY_INTEGER;*/DECLARETYPE name_table_type IS TABLE OF VARCHAR2(50)INDEX BY BINARY_INTEGER;n name_table_type;BEGINn(-7) := 'tom';n(4) := 'jack';n(9) := 'rose';dbms_output.put_line('元素的长度:' || n.count);dbms_output.put_line(n(4));END; --表类型的常⽤属性DECLARETYPE name_table_type IS TABLE OF VARCHAR2(50)INDEX BY BINARY_INTEGER;n name_table_type;BEGIN--设置元素n(-5) := 'tom';n(3) := 'jack';n(17) := 'rose';n(23) := 'zhang';n(24) := 'wangwu';--删除指定下标的元素--n.delete(17);--删除⼀个范围的元素--n.delete(10,24);--删除所有元素--n.delete;--返回元素长度dbms_output.put_line('元素个数:' || n.count);--判断下标是否存在IF n.exists(17) THENdbms_output.put_line('true');ELSEdbms_output.put_line('false');END IF;--输出最⼩下标dbms_output.put_line(n.first);--输出最⼤下标dbms_output.put_line(st);--返回指定下标的元素dbms_output.put_line(n(3));--返回上⼀个或下⼀个存在的下标,如果没有,返回NULLdbms_output.put_line(n.next(10));dbms_output.put_line(n.prior(10));END;--BULK COLLECT INTO:把查询结果⼀次性赋给⼀个表类型的变量,下标⾃动从1开始递增 --查询所有的员⼯姓名,存储到⼀个表类型的变量中DECLARETYPE name_table_type IS TABLE OF VARCHAR2(50)INDEX BY BINARY_INTEGER;n name_table_type;BEGINSELECT last_name BULK COLLECT INTO nFROM employees;dbms_output.put_line('元素长度:' || n.count);dbms_output.put_line(n(2));END;--查询所有的员⼯信息,存储到⼀个表类型的变量中DECLARETYPE emp_table_type IS TABLE OF employees%ROWTYPEINDEX BY BINARY_INTEGER;e emp_table_type;BEGINSELECT * BULK COLLECT INTO eFROM employees;dbms_output.put_line('元素长度:' || e.count);dbms_output.put_line(e(2).last_name);dbms_output.put_line(e(3).salary);END; 8,DML语句返回值:--RETURNING语句:DML操作返回值赋给变量RETURN 列1,列2,... INTO 变量1,变量2,...--更新某个员⼯的⼯资,输出这个员⼯姓名,新⼯资DECLAREv_empid employees.employee_id%TYPE := 100;v_name st_name%TYPE;v_money employees.salary%TYPE := 1;v_salary employees.salary%TYPE;BEGINUPDATE employeesSET salary=salary+v_moneyWHERE employee_id=v_empidRETURNING last_name,salaryINTO v_name,v_salary;dbms_output.put_line('姓名:' || v_name);dbms_output.put_line('新⼯资:' || v_salary);END; --插⼊语句中使⽤RETURNING语句:DECLAREd dept%ROWTYPE;BEGININSERT INTO dept VALUES (50,'AA','BB')RETURN deptno,dname,loc INTO d;dbms_output.put_line(d.deptno);dbms_output.put_line(d.dname);dbms_output.put_line(d.loc);END; --删除语句中使⽤RETURNING语句DECLAREd dept%ROWTYPE;BEGINDELETE FROM deptWHERE deptno=50RETURN deptno,dname,loc INTO d;dbms_output.put_line(d.deptno);dbms_output.put_line(d.dname);dbms_output.put_line(d.loc);END; --DML操作返回多⾏数据--更新某个部门的员⼯的⼯资,返回被更新的员⼯姓名,新⼯资DECLARETYPE emp_record_type IS RECORD (ename st_name%TYPE,salary employees.salary%TYPE);TYPE emp_table_type IS TABLE OF emp_record_typeINDEX BY BINARY_INTEGER;e emp_table_type;BEGINUPDATE employeesSET salary=salary+1WHERE department_id=50RETURN last_name,salary BULK COLLECT INTO e; dbms_output.put_line('更新了' || e.count || '个员⼯'); dbms_output.put_line(e(1).ename || ',' || e(1).salary); END;。
第二部分PL/SQL程序设计基础陈卫星目录第一章PL/SQL 程序设计简介 (4)§1.2SQL与PL/SQL (4)§1.2.1 什么是PL/SQL? (4)§1.2.1 PL/SQL的好处 (4)§1.2.2 PL/SQL 可用的SQL语句 (5)§1.3运行PL/SQL程序 (5)第二章PL/SQL块结构和组成元素 (6)§2.1PL/SQL块 (6)§2.2PL/SQL结构 (6)§2.3标识符 (6)§2.4PL/SQL变量类型 (7)§2.4.1 变量类型 (7)§2.4.2 复合类型(记录和表) (9)§2.4.3 使用%ROWTYPE (10)§2.4.4 LOB类型* (11)§2.4.5 用户定义的子类型 (11)§2.4.6 数据类型的转换* (13)§2.5运算符和表达式(数据定义) (13)§2.5.1 关系运算符 (13)§2.5.2 一般运算符 (13)§2.5.3 逻辑运算符 (13)§2.6变量赋值 (14)§2.6.1 字符及数字运算特点 (14)§2.6.2 BOOLEAN 赋值 (14)§2.6.3 数据库赋值 (14)§2.6.4 可转换的类型赋值 (15)§2.7变量作用范围及可见性 (15)§2.8注释 (16)§2.9简单例子 (16)§2.9.1 简单数据插入例子 (16)§2.9.2 简单数据删除例子 (17)第三章PL/SQL流程控制语句 (18)§3.1条件语句 (18)§3.2循环 (19)§3.3标号和GOTO (21)§3.4NULL语句 (21)第四章游标的使用 (22)§4.1游标概念 (22)§4.1.1 处理显式游标 (22)§4.1.2 处理隐式游标 (26)§4.2游标循环小结 (27)§4.2.1 简单循环 (27)§4.2.2 WHILE循环 (28)§4.2.3 游标FOR循环语句 (28)§4.2.4 关于NO_DATA_FOUND 和%NOTFOUND的区别 (29)§4.2.5 游标修改和删除操作 (29)§4.3游标变量 (30)§4.3.1 声明游标变量 (30)§4.3.2 游标变量操作 (31)§4.3.3 游标变量应用 (31)第五章异常错误处理 (32)§5.1异常处理概念 (32)§5.1.1 预定义的异常处理 (33)§5.1.2 非预定义的异常处理 (34)§5.1.3 用户自定义的异常处理 (34)§5.1.4 用户定义的异常处理 (35)§5.2异常错误传播 (37)§5.2.1 在执行部分引发异常错误 (37)§5.2.2 在声明部分引发异常错误 (37)§5.3异常错误处理编程 (38)§5.4在PL/SQL中使用SQLCODE,SQLERRM (38)第六章存储函数和过程 (40)§6.1引言 (40)§6.2创建函数 (40)§6.3存储过程 (43)§6.3.1 创建过程 (43)§6.3.2 使用过程 (45)§6.3.3 开发存储过程步骤 (47)§6.3.4 与过程相关数据字典( P112) (48)§6.4过程和函数中的异常处理 (48)§6.4.1 使用系统定义的异常处理 (48)§6.4.2 使用用户定义的异常处理+ (49)第七章包的创建和应用 (50)§7.1引言 (50)§7.2包的定义 (50)§7.3包的开发步骤 (51)§7.4包定义的说明 (51)§7.5子程序重载 (59)§7.6删除过程、函数和包 (60)§7.7包的管理 (61)第八章触发器 (62)§8.1触发器类型 (62)§8.1.1 DML触发器 (62)§8.1.2 替代触发器 (62)§8.1.3 系统触发器 (62)§8.2创建触发器 (62)§8.2.1 触发器触发次序 (64)§8.2.2 创建DML触发器 (64)§8.2.3 创建替代(Instead_of)触发器 (65)§8.2.3 创建系统事件触发器 (65)§8.2.4 系统触发器事件属性 (66)§8.2.5 使用触发器谓词 (67)§8.2.6 重新编译触发器 (67)§8.3删除和使能触发器 (67)§8.4触发器和数据字典 (68)§8.5数据库触发器的应用举例 (68)§8.6数据库触发器的应用实例 (78)第一章PL/SQL 程序设计简介PL /SQL是一种高级数据库程序设计语言,该语言专门用于在各种环境下对ORACLE数据库进行访问。
Oracle PLSQL语言初级教程Oracle PL/SQL语言初级教程Oracle PL/SQL语言基础 ..................................................................... ...................................................... 3 PL/SQL的复合数据类型...................................................................... ..................................................... 16 使用集合 ..................................................................... ........................................................................ . (23)PL/SQL单行函数和组函数详解...................................................................... .......................................... 27 Oracle数据库数据对象分析 ..................................................................... .............................................. 41 Oracle完整性约束 ..................................................................... . (47)索引(INDEXES) .............................................................. ........................................................................ .. 53Oracle过程和函数 ..................................................................... . (54)触发器(Triggers) ............................................................. . (57)数据字典 ..................................................................... ........................................................................ . (58)Oracle操作和控制语言...................................................................... ..................................................... 61 建立和修改用户 ..................................................................... .. (67)ORACLE游标 ..................................................................... ........................................................................73ORACLE异常处理 ..................................................................... . (83)PL/SQL是Oracle对标准数据库语言的扩展,Oracle公司已经将PL/SQL整合到Oracle 服务器和其他工具中了,近几年中更多的开发人员和DBA开始使用PL/SQL,本教程将以循速渐进的方式讲述PL/SQL基础语法,结构和组件、以及如何设计并执行一个PL/SQL程序,通过本教程的学习,您将初步掌握PL/SQL语言,能够利用PL/SQL语言完成建表、查询、添加、删除数据以及事务处理语句的基本用法。
plsql教程PL/SQL是一种与Oracle数据库一起使用的过程化编程语言。
它是操纵、定义和控制Oracle数据库对象的语言,并提供了一种编写存储过程、触发器、函数、包等数据库程序模块的方式。
PL/SQL的基本语法与SQL相似,可以执行SQL语句和存储过程的调用。
以下是一些常用的PL/SQL代码示例:1. 声明变量和常量:```DECLAREnum1 NUMBER := 10;text1 VARCHAR2(20) := 'Hello';constant1 CONSTANT NUMBER := 5;BEGIN-- 执行代码END;```2. 条件语句:```IF num1 > 0 THENNULL;ELSIF num1 = 0 THENNULL;ELSENULL;END IF;```3. 循环语句:```FOR i IN 1..5 LOOPNULL;END LOOP;WHILE num1 > 0 LOOP NULL;num1 := num1 - 1; END LOOP;LOOPNULL;EXIT WHEN num1 = 0; num1 := num1 - 1; END LOOP;```4. 异常处理:```BEGIN-- 执行代码EXCEPTIONWHEN OTHERS THEN -- 处理异常END;```5. 创建存储过程:```CREATE OR REPLACE PROCEDURE procedure_name (param1 IN NUMBER, param2 OUT VARCHAR2) IS-- 变量声明BEGIN-- 执行代码param2 := 'Hello';END;```这些只是PL/SQL语言的一部分功能和用法。
通过学习和实践,您可以掌握更多PL/SQL的知识和技巧,提高数据库编程的效率和质量。
数据库培训-PLSQL数据库培训 PLSQL在当今数字化的时代,数据库管理和编程技能变得愈发重要。
PL/SQL(Procedural Language/Structured Query Language)作为一种强大的数据库编程语言,在企业级应用开发中发挥着关键作用。
无论是处理复杂的业务逻辑、提高数据库性能,还是确保数据的准确性和完整性,PL/SQL 都有着出色的表现。
接下来,让我们深入了解一下PLSQL 培训的相关内容。
PL/SQL 是 Oracle 数据库对 SQL 语言的过程化扩展。
它将 SQL 语言的强大查询能力与过程化编程语言的控制结构相结合,使得开发者能够在数据库内部编写复杂的逻辑和操作。
通过使用 PLSQL,我们可以创建存储过程、函数、触发器等数据库对象,从而实现更高效、更灵活的数据处理。
在 PLSQL 培训中,首先要掌握的是基本语法。
这包括变量的定义和使用、数据类型的选择、控制结构(如条件判断、循环)等。
例如,我们可以使用`DECLARE` 关键字来定义变量,像这样:```sqlDECLAREv_name VARCHAR2(50);v_age NUMBER;BEGIN后续代码中使用变量进行操作END;```数据类型的选择也非常重要,常见的数据类型有字符型(如`VARCHAR2` )、数值型(如`NUMBER` )、日期型(如`DATE` )等。
掌握了基本语法后,接下来就是学习如何进行数据库操作。
PL/SQL 可以与SQL 语句无缝集成,方便我们对数据库中的表进行查询、插入、更新和删除等操作。
比如,要从一个名为`employees` 的表中查询数据,可以这样写:```sqlDECLAREv_employee_id NUMBER;v_employee_name VARCHAR2(50);BEGINSELECT employee_id, employee_name INTO v_employee_id,v_employee_nameFROM employeesWHERE department_id = 10;对获取到的数据进行进一步处理END;```存储过程是 PLSQL 中的重要概念之一。
PL/SQL基本操作手册PL/SQL(Procedural Language/Structured Query Language)是一种基于SQL 语言的过程编程语言,它在Oracle数据库中非常常见。
本文将介绍PL/SQL的基本操作,如变量、控制语句、游标等。
变量和常量变量可以使用DECLARE语句声明。
在代码中,变量必须指定它们的类型,例如NUMBER、VARCHAR2或BOOLEAN。
DECLAREv_employee_id NUMBER:=100;v_employee_name VARCHAR2(50) :='John Doe';v_is_hired BOOLEAN:=TRUE;BEGIN-- code goes hereEND;常量是一个不可变的参数,可以使用CONSTANT关键字定义。
常量的值不会在程序中更改。
DECLAREc_tax_rate CONSTANT NUMBER(4, 2) :=0.08;BEGIN-- code goes hereEND;控制语句控制语句提供了决策和循环结构。
IF语句IF语句用于对一个表达式进行测试,以确定哪个分支应该执行。
IF expression THEN-- code goes hereELSIF expression THEN-- code goes hereELSE-- code goes hereEND IF;CASE语句CASE语句用于检查多个可能的条件。
CASE expressionWHEN value1 THEN-- code goes hereWHEN value2 THEN-- code goes hereELSE-- code goes hereEND CASE;LOOP语句LOOP语句用于无限的循环,可以通过某些条件来终止循环。
LOOP-- code goes hereEXIT WHEN expression;END LOOP;WHILE语句WHILE语句用于执行一系列语句,只要指定条件为TRUE。
第4章PL/SQL语言基础本章学习内容1. PL/SQL语言简介2. 程序结构3. 流程控制4. 异常处理5. 开发动态SQL本章学习目标1. 掌握PL/SQL程序结构2. 掌握PL/SQL流程控制3. 掌握PL/SQL异常处理4. 掌握PL/SQL中开发动态SQL本章简介在第3章中,我们已经学习了同义词、序列、视图、索引等知识。
并通过同义词以一种非常简便的方式去访问其它方案中的对象;通过视图将一些复杂的SQL语句封装起来方便使用;通过序列作为表的自动编号并做为主键实现了数据库的实体完整性;通过使用各种索引在数据量非常宠大的表中提高查询效率。
但是要实现复杂的商用业务逻辑仅凭这些对象是远远不够的,我们必须使用程序流程控制和异常处理机制等。
本章将继续学习程序结构、流程控制、异常处理、开发动态SQL等知识。
流程控制是PL/SQL 对SQL最重要的扩展。
流程控制结构包括条件控制、循环控制和顺序控制,流程控制为我们提供了实现复杂业务逻辑的一种途径。
为处理程序中的异常,PL/SQL提供了一种异常错误处理机制,可以帮助实现对错误的捕获和处理,当异常发生时,PL/SQL会自动地捕获异常并自动地将程序控制流程转移到异常处理部分的程序。
在PL/SQL程序设计中,可以直接使用DML和事务控制的语句,但DDL语句及系统控制语句却不能在PL/SQL中直接使用。
如果需要在PL/SQL中使用DDL语句及系统控制语句,可以通过使用动态SQL来实现,如需要动态建表或某个不确定的操作需要动态执行。
4.1PL/SQL语言简介4.1.1 PL/SQL概述PL/SQL是Oracle在标准SQL语言上的过程性扩展,它不仅允许嵌入SQL语句,而且允许定义变量和常量,允许过程语言结构(条件分支语句和循环语句),允许使用异常来处理Oracle错误等。
在任何运行Oracle的平台上,应用开发人员都可以使用PL/SQL。
通过使用PL/SQL,可以在一个PL/SQL块中包含多条SQL语句和PL/SQL语句。
第4章PL/SQL语言基础本章学习内容1. PL/SQL语言简介2. 程序结构3. 流程控制4. 异常处理5. 开发动态SQL本章学习目标1. 掌握PL/SQL程序结构2. 掌握PL/SQL流程控制3. 掌握PL/SQL异常处理4. 掌握PL/SQL中开发动态SQL本章简介在第3章中,我们已经学习了同义词、序列、视图、索引等知识。
并通过同义词以一种非常简便的方式去访问其它方案中的对象;通过视图将一些复杂的SQL语句封装起来方便使用;通过序列作为表的自动编号并做为主键实现了数据库的实体完整性;通过使用各种索引在数据量非常宠大的表中提高查询效率。
但是要实现复杂的商用业务逻辑仅凭这些对象是远远不够的,我们必须使用程序流程控制和异常处理机制等。
本章将继续学习程序结构、流程控制、异常处理、开发动态SQL等知识。
流程控制是PL/SQL对SQL最重要的扩展。
流程控制结构包括条件控制、循环控制和顺序控制,流程控制为我们提供了实现复杂业务逻辑的一种途径。
为处理程序中的异常,PL/SQL提供了一种异常错误处理机制,可以帮助实现对错误的捕获和处理,当异常发生时,PL/SQL会自动地捕获异常并自动地将程序控制流程转移到异常处理部分的程序。
在PL/SQL程序设计中,可以直接使用DML和事务控制的语句,但DDL语句及系统控制语句却不能在PL/SQL中直接使用。
如果需要在PL/SQL中使用DDL语句及系统控制语句,可以通过使用动态SQL来实现,如需要动态建表或某个不确定的操作需要动态执行。
4.1PL/SQL语言简介4.1.1PL/SQL概述PL/SQL是Oracle在标准SQL语言上的过程性扩展,它不仅允许嵌入SQL语句,而且允许定义变量和常量,允许过程语言结构(条件分支语句和循环语句),允许使用异常来处理Oracle错误等。
在任何运行Oracle的平台上,应用开发人员都可以使用PL/SQL。
通过使用PL/SQL,可以在一个PL/SQL块中包含多条SQL语句和PL/SQL语句。
PL/SQL可以用于创建存储过程、触发器和程序包等,也可以用于处理业务规则、数据库事件或给SQL命令的执行添加程序逻辑。
4.1.2PL/SQL优点PL/SQL是一种可移植的高性能事务处理程序,它支持SQL和面向对象编程,提供了良好的性能和高效的处理能力,具有以下6个方面的优点。
1. 提高应用程序的运行性能在编写Oracle数据库应用程序时,开发人员可以直接将PL/SQL块内嵌到应用程序中,其最大的优点是可以降低网络开销、提高应用程序性能。
对于其他异构数据库(例如SQLServer、Sybase、DB2等),当应用程序访问RDBMS时,每次只能发送单条SQL语句。
而对于Oracle数据库而言,通过使用PL/SQL块,可以将多条SQL语句组织到同一个PL/SQL块中,从而降低了网络开销,提高了应用程序的性能。
2. 提供模块化的程序设计功能当开发数据库应用程序时,为了简化客户端应用程序的开发和维护工作,可以首先将企业规则或商业逻辑集成到PL/SQL子程序(过程、函数和包)中,然后在应用程序中调用子程序实现相应的程序功能。
3. 允许定义标识符当使用PL/SQL开发应用模块时,为了使应用模块与应用环境实现数据交互,需要定义变量、常量、游标等各种标识符。
例如,函数get_sal中的no为输入参数,用于接收雇员编号的输入值,而salary变量则用于临时存储雇员工资。
4. 具有过程语言控制结构PL/SQL是Oracle在标准SQL上的过程性扩展,它不仅允许在PL/SQL块内嵌入SQL语句,而且允许在PL/SQL块中使用各种类型的条件分支语句和循环语句。
5. 具有良好的兼容性PL/SQL是Oracle所提供的用于实现应用模块的语言,在允许运行Oracle的任何平台上都可以使用PL/SQL。
例如,不仅可以在Oracle数据库中使用PL/SQL开发数据库端的过程、函数和触发器,也可以在Oracle提供的应用开发工具Developer中使用PL/SQL开发客户端的过程、函数和触发器。
6. 处理运行错误当设计并开发应用程序时,为了提高应用程序的健壮性,可以使用PL/SQL所提供的异常处理(EXCEPTION)集中处理各种Oracle错误和PL/SQL错误,从而简化错误处理。
4.1.3PL/SQL块所有的PL/SQL程序都以块作为基本单位组成。
块中包含过程化语句和SQL的DML语句。
这些块可以按顺序出现,也可以相互嵌套(一个块在另一个块的内部)。
按是否带有名称以及在数据库中的存储方式,块可以分为以下5类。
1. 匿名块匿名块是出现在应用程序中的没有名字且不存储到数据库中的块。
匿名块可以出现在SQL语句可以出现的地方,它们可以调用其他程序,却不能被其他程序调用。
2. 命名块命名块是一种带有标签的匿名块,标签为块指定了一个名称。
3. 子程序子程序是存储在数据库中的过程(procedure)、函数(function),生成之后可以被多次执行。
4. 程序包程序包是存储在数据库中的一组子程序、变量定义。
程序包中的子程序可以被其他程序包或者子程序调用。
如果声明为局部子程序,则只能在定义该局部子程序的块中调用该局部子程序。
5. 触发器触发器是一种存储在数据库中的命名块,生成之后可以被多次执行。
在相应的触发器事件发生之前或之后就会被执行一次或多次(每行记录一次)。
触发器事件一般是指对特定的数据库表、视图进行的操作,如INSERT、UPDATE和DELETE等(称为DML触发器);或者对数据库级的操作,如关闭、启动、登录、退出数据库,创建对象、修改对象、删除对象等(称为系统触发器)。
4.2程序结构4.2.1组成部分PL/SQL程序块由3个部分组成:定义部分、执行部分和异常处理部分。
其中,定义部分用于定义常量、变量、游标、异常和复杂数据类型等;执行部分用于实现应用模块功能,该部分包含需要执行的PL/SQL语句和SQL语句;异常处理部分用于处理执行部分可能出现的运行错误。
PL/SQL块的基本结构如下:DECLARE定义部分BEGIN执行部分EXCEPTION异常处理部分END;其中,定义部分以DECLARE开始,该部分是可选的;执行部分以BEGIN开始,该部分是必须的;异常处理部分以EXCEPTION开始,该部分是可选的;END则是PL/SQL程序块的结束标记。
创建一个匿名程序块,该程序块用于接收用户输入的部门名称,计算并输出该部门总工资,还用于处理用户输入的部门名称在库中不存在的异常,如图1.4.1所示。
1. 设置输出、显示环境变量2. 定义块变量3. 执行业务逻辑4. 异常处理部分图1.4.3 声明和使用变量、常量2. 使用SELECT INTO语句给变量赋值除了可以使用常量来给变量赋值之外,还可以从数据库表中查询获得值来赋予变量。
图1.4.4中演示了通过SELECT INTO语句将从数据库表中查询的结果赋予变量的过程,根据雇员编号,查询获得雇员工资、补助和总工资。
图1.4.4 使用SELECT INTO语句给变量赋值4.2.4数据类型编写PL/SQL程序时,若临时存储数值,则必须定义变量和常量;若在应用环境和子程序之间传递数据,则必须为子程序指定参数。
而在PL/SQL程序中定义变量、常量和参数时,必须为它们指定PL/SQL数据类型。
1. CHARCHAR表示固定长度字符串,长度不够的使用空格来补充,最多可以存储2000字节。
2. VARCHAR2VARCHAR2表示可变长度字符串,最多可以存储4000字节。
3. NUMBERNUMBER类型可以存储正数、负数、零、定点数和精度为38位的浮点数。
其格式为:NUMBER(M,N)。
其中,M表示精度,代表数字的总位数;N表示小数点右边,数字的位数。
4. DATE类型DATE数据类型用于存储表中的日期和时间数据,取值范围是公元前4712年1月1日至公元9999年12月31日。
DATE类型的长度是7,7个字节分别表示世纪、年、月、日、时、分和秒。
5. TIMESTAMP类型TIMESTAMP数据类型用于存储日期的年、月、日、小时、分和秒值。
其中,秒值精确到小数点6位,该数据类型同时包含时区信息。
6. CLOB大字符串对象类型CLOB数据类型用于存储可变长度的字符数据,最多可存储4GB。
该数据类型用于存储VARCHAR2类型不能存储的长文本信息。
7. BLOB大二进制类型BLOB数据类型用于存储较大的二进制对象,如图形、视频剪辑和声音剪辑等,该类型最多可以存储4GB数据。
8. %TYPE当定义PL/SQL变量存放值时,必须确保变量使用合适的数据类型和长度,否则可能会在运行过程中出现PL/SQL运行错误。
为了避免这种不必要的错误,可以使用%TYPE属性来定义变量。
当使用%TYPE属性定义变量时,Oracle会自动地按照数据库列或其他变量来确定新变量的类型和长度。
图1.4.5将演示使用%TYPE定义变量的过程。
图1.4.5 使用%TYPE定义变量由图1.4.5可知,变量v_ename、v_sal与EMP表的ename列、sal列的数据类型和长度完全一致,而变量v_tax_sal与变量v_sal的数据类型和长度完全一致。
因此,当ename列和sal列的类型和长度发生改变时,该PL/SQL块将不需要进行任何修改。
9. %ROWTYPE如果一张表中包含较多的列,则可以使用%ROWTYPE来定义一个表示表中一行记录的变量,这种方式比分别使用%TYPE来定义表示表中各个列的变量要简洁得多。
为了使一个变量的数据类型与一张表中记录的各个列的数据类型对应一致,Oracle提供了%ROWTYPE定义方式。
图1.4.7 定义并使用RECORD数据类型11. TABLE索引表相当于一个键值集合,键是唯一的,用于查找对应的值。
键可以是整数或字符串。
语法:TYPE table_name IS TABLE OF element_type [NOT NULL]INDEX BY [BINARY_INTEGER | PLS_INTEGER | VARCHAR2];关键字INDEX BY表示创建一个主键索引,以便引用记录表变量中的特定行。
图1.4.8将演示索引表数据类型的定义及使用过程。
图1.4.8 定义并使用TABLE数据类型图1.4.8中的v_emp_empnos和v_emp_enames变量都按类似一维数组的方式来使用。
在定义TABLE数据类型时,如果指定element_type参数值为%ROWTYPE类型,则TABLE数据类型就可以按类似二维数组的方式来使用,类似于数据库中表的结构。
图1.4.9将演示TABLE数据类型作为二维数组使用的过程。