Pl/SQL 编程
Pl/SQL 编程
一:前言
二:Pl/Sql 概述
二 —— 1: Pl/Sql块结构
SQL> set serveroutput on;
SQL>
SQL> declare
2 a int:=10;
3 b int:=200;
4 c number;
5 begin
6 c:=(a+b)/(a-b);
7 dbms_output.put_line(c);
8 exception
9 when zero_divide then
10 dbms_output.put_line('除数不许为零');
11 end;
12 / -1.10526315789473684210526315789473684211 PL/SQL procedure successfully completed SQL>
二 —— 2: 代码注释和标识符
二 —— 2_____1:单行注释
SQL> set serveroutput on; --在服务器端 输出结果
SQL> declare
2
3 Num_sal number; --- 声明一个数值变量
4 Var_ename varchar(20); --- 声明一个字符串变量
5 begin
6 select e.ename,e.sal into Var_ename,Num_sal from emp e where empno=7839; --检索指定的值并储存到变量中
7 dbms_output.put_line(Var_ename||'工资是'||Num_sal);
8 end;
9
10
11 / KING工资是5000 PL/SQL procedure successfully completed
二 —— 2_____2:多行注释
二 —— 2_____3:PL/SQL字符集
三:数据类型与定义变量和常量
三 —— 1:基本数据类型
三 —— 1_____1:数值类型
三 —— 1_____2:字符类型
三 —— 1_____3:日期类型
三 —— 1_____4:布尔类型
三 —— 2 :特殊数据类型
三 —— 2_____1: %TYPE 类型
SQL> set serveroutput on /*在服务器端 输出结果*/
SQL> declare
2 var_ename emp.ename%type; /*声明与ename 列类型相同的变量*/
3 var_job emp.job%type; /*声明与job列类型相同的变量*/
4 begin
5 select ename,job into var_ename,var_job from emp where empno=7839 ;/*检索数据,并保存在变量中*/
6 dbms_output.put_line(var_ename||'工资是'||var_job);
7 end;
8 / KING工资是PRESIDENT PL/SQL procedure successfully completed
三 —— 2_____2: record 类型
set serveroutput on /**/
declare
type emp_type is record
(
var_ename varchar2(20), /*定义字段--成员变量 */
var_job varchar2(20),
var_sal number
);
empinfo emp_type; /*定义变量*/
begin
select ename,job,sal into empinfo from emp where empno=7839 ;/*检索数据*/
dbms_output.put_line( '雇员'||empinfo.var_ename||'的职位是'||empinfo.var_job||'、工资是'||empinfo.var_sal); end;
/
三 —— 2_____3: %rowtype 类型
SQL> set serveroutput on
SQL> declare
2 rowVar_emp emp%rowtype;/*定义能够储存emp表中一行数据的变量 rowVar_emp*/
3 begin
4 select * into rowVar_emp from emp where empno=7839 ;/*检索数据*/
5 dbms_output.put_line( '雇员'||rowVar_emp.ename||'的职位是'||rowVar_emp.job||'、工资是'||rowVar_emp.sal);
6
7 end;
8 / 雇员KING的职位是PRESIDENT、工资是5000 PL/SQL procedure successfully completed SQL>
三 —— 3: 定义变量和常量
四 :流程控制语句
四 —— 1:选择语句 if …then 语句
SQL> set serveroutput on
SQL> declare
2 var_name1 varchar2(50); --//定义2个字符串变量
3 var_name2 varchar2(50);
4
5 begin
6 var_name1 :='East'; --//给2个变量赋值
7 var_name2 :='xiaoke';
8
9 if length(var_name1)<length(var_name2) then
10 /*输出比较后的结果*/
11 dbms_output.put_line('字符串 “'||var_name1||'”的长度比字符串“'||var_name2||'”的长度小');
12 end if;
13 end;
14 / 字符串 “East”的长度比字符串“xiaoke”的长度小 PL/SQL procedure successfully completed SQL>
四 ——1_____ 2:选择语句 if …then … else 语句
四 ——1_____3:选择语句 if …then … elseif 语句
SQL> set serveroutput on
SQL> declare
2 month int :=10; /*声明整型变量并赋值*/
3
4 begin
5 if month >=0 and month<=3 then /*判断春节*/
6 dbms_output.put_line('这是春季');
7 elsif month >=4 and month <=6 then /*片段夏季*/
8 dbms_output.put_line('这是夏季');
9 elsif month >=7 and month<=9 then
10 dbms_output.put_line('这是秋季');
11 elsif month >=10 and month<=12 then
12 dbms_output.put_line('这是冬季');
13 else
14 dbms_output.put_line('对不起,月份不合法!');
15 end if;
16 end;
17 / 这是冬季 PL/SQL procedure successfully completed SQL>
四 ——1_____4:选择语句 case 语句
SQL> set serveroutput on
SQL> declare
2 season int:=3;/*定义整型变量并赋值*/
3 aboutInfo varchar2(50);/*声明月份信息*/
4 begin
5 case season /*片段月份*/
6 when 1 then
7 aboutInfo := season || '季度包括 1,2,3月份';
8 when 2 then
9 aboutInfo := season || '季度包括 4,5,6月份';
10 when 3 then
11 aboutInfo := season || '季度包括 7,8,9月份';
12 when 4 then
13 aboutInfo := season || '季度包括 10,11,12月份';
14 else
15 aboutInfo := season || ' 季度不合法';
16 end case ;
17
18 dbms_output.put_line(aboutInfo);
19
20 end;
21 / 3季度包括 7,8,9月份 PL/SQL procedure successfully completed SQL>
四 ——2:循环语句
四 ——2_____1: loop 语句
四 ——2_____2: while 语句
四 ——2_____3: for 语句
五 :Pl/Sql 游标
五—1:显示游标
五——1_____1:声明游标
五——1_____2:打开游标
五——1_____3: 读取游标
set serveroutput on
declare
/*声明游标,检索雇员信息*/
cursor cur_emp(var_job varchar2 := 'SALESMAN') is
select empno, ename, sal from emp where job = var_job;
type record_emp is record /*声明一个记录类型 record 类型*/
(
/*定义当前记录的成员变量*/
var_empno emp.empno%type,
var_ename emp.ename%type,
var_sal emp.sal%type);
emp_row record_emp; /*声明一个record_emp 类型变量*/
begin
open cur_emp('MANAGER'); /*打开游标*/
fetch cur_emp
into emp_row; /*先让指针指向结果集中的第一行,并将值保存到emp_row 中*/
while cur_emp%found loop
dbms_output.put_line(emp_row.var_ename || '的编号是' || emp_row.var_empno ||
',工资是' || emp_row.var_sal); fetch cur_emp
into emp_row; /*让指针指向结果集的下一行,并将值保存到emp_row中*/
end loop;
close cur_emp; /*关闭游标*/
end;
/
五——1_____4: 关闭游标
五——2: 游标的属性
set serveroutput on
declare
var_ename varchar2(50);/*声明变量,用来储存雇员名称*/
var_job varchar2(50);/*声明变量,用来储存雇员的职务*/
/*声明游标,检索指定员工编号的雇员信息*/
cursor cur_emp /*定义游标,检索指定编号的记录信息*/
is select ename ,job from emp where empno=7499;
begin
open cur_emp;/*打开游标*/
fetch cur_emp into var_ename,var_job ;/*读取游标,并且储存雇员名称和职务*/
if cur_emp%found then /*若检索到数据记录,则输出雇员信息*/
dbms_output.put_line('编号是7499的雇员名称为'||var_ename||',职务是:'||var_job);
else
dbms_output.put_line('无数据记录');/*提示无记录信息*/
end if;
end;
/
五——3: 隐式游标
/*在scott 用户下,把emp 表中销售员(即:SALESMAN)的工资上调20% 然后使用隐式游标sql的%rowcount属性输出上调工资的员工数量*/
set serveroutput on
begin
update emp set sal=sal*(1+0.2) where job='SALESMAN';/*把销售员工的工资上调20%*/
if sql%notfound then
dbms_output.put_line(' 没有雇员需要上调工资');
else
dbms_output.put_line('有'||sql%rowcount||'个雇员工资上调20%');
end if;
end;
/
五——3: 通过for 语句循环游标
/*使用隐式游标和for语句检索出职务是销售员的雇员信息并输出*/
set serveroutput on
begin
for emp_record in(select empno,ename,sal from emp where job='SALESMAN') /*遍历隐式游标中的记录*/
loop
dbms_output.put_line('雇员编号:'|| emp_record.empno); /*输出雇员编号*/
dbms_output.put_line('雇员名称:'|| emp_record.ename);/*输出雇员名称*/
dbms_output.put_line('雇员工资:'|| emp_record.sal); /*输出雇员工资*/
end loop;
end;
//*使用显示游标 和 for 语句检索出部门编号是30的雇员信息并输出 */
set serveroutput on
declare
cursor cur_emp is select * from emp where deptno =30; /*检索部门编号为30的雇员信息*/
begin
for emp_rocord in cur_emp/*遍历雇员信息*/
loop
dbms_output.put_line('雇员编号:'|| emp_rocord.empno); /*输出雇员编号*/
dbms_output.put_line('雇员名称:'|| emp_rocord.ename);/*输出雇员名称*/
dbms_output.put_line('雇员职务:'|| emp_rocord.job); /*输出雇员工资*/
end loop;
end;
/
六: PL/SQL 异常处理
六——1_____1: 预定义异常
/*使用select into语句检索emp 表中部门编号为10 的雇员编号记录信息 然后使用too_many_rows一定*/ set serveroutput on
declare
var_empno number ;/*定义变量,储存雇员编号*/
var_ename varchar2(50);/*定义变量,储存雇员名称*/
begin
select empno,ename into var_empno,var_ename from emp where deptno=10;/*查询部门编号为10的雇员的信息*/
if sql%found then /*如果检索成功,则输出雇员信息*/
dbms_output.put_line('雇员编号:'||var_empno||';雇员名称:'||var_ename);
end if;
exception /*捕获异常*/
when too_many_rows then /*若 select into 语句返回的记录超过一行*/
dbms_output.put_line('返回记录超出一行');
when no_data_found then /*若select into 语句的返回结果为0行*/
dbms_output.put_line('无数据记录');
end;
/
六——2: 自定义异常
六——2_____1: 错误编号异常
set seroutput on
declare
primary_iterant exception;/*定义野怪异常变量*/
pragma exception_init(primary_iterant,-00001);/*关联错误号 和 异常变量名*/
begin
/*向dept表中插入一条与已有主键值重复的记录,以便引发异常*/
insert into dept values(10,'rrr','rrr');
exception
when primary_iterant then /*若Oracle系列捕获到的异常为-000001异常*/
dbms_output.put_line('主键不允许重复!'); /*输出异常描述信息*/
end;
/
六——2_____2: 业务逻辑异常
set serveroutput on
declare
null_exception exception ;/*声明一个exception 类型的异常变量*/
dept_row dept%rowtype; /*声明rowtype 类型的变量 dept_now*/
begin
dept_row.deptno :=66; /*给部门编号变量赋值*/
dept_row.dname := '公关部';/*给部门名称变量赋值*/
insert into dept values(dept_row.deptno,dept_row.dname,dept_row.loc);/*向dept表插入一条记录*/
if dept_row.loc is null then
raise null_exception; /*引发 null 异常 程序进入exception部分*/
end if;
exception
when null_exception then /*当 raise 引发的异常是 null_exception 时*/
dbms_output.put_line('loc 字段的值不允许为null'); /*则输出异常提示信息*/
rollback; /*回滚插入的数据记录*/
end ;
/
六——2_____3: Oracle存储过程的异常处理
注:本段内容来源于:《Oracle存储过程的异常处理》
1、为了提高存储过程的健壮性,避免运行错误,当建立存储过程时应包含异常处理部分。
2、异常(EXCEPTION)是一种PL/SQL标识符,包括预定义异常、非预定义异常和自定义异常;
3、预定义异常是指由PL/SQL提供的系统异常;非预定义异常用于处理与预定义异常无关的Oracle错误(如完整性约束等);自定义异常用于处理与Oracle错误的其他异常情况。
4、RAISE_APPLICATION_ERROR用于自定义错误消息,并且消息号必须在-20000~-20999之间命名的系统异常 产生原因
access_into_null 未定义对象
case_not_found case中若未包含相应的when,并且没有设置
collection_is_null 集合元素未初始化
curser_already_open 游标已经打开
dup_val_on_index 唯一索引对应的列上有重复的值
invalid_cursor 在不合法的游标上进行操作
invalid_number 内嵌的 sql 语句不能将字符转换为数字
no_data_found 使用 select into 未返回行,或应用索引表未初始化的
too_many_rows 执行 select into 时,结果集超过一行
zero_divide 除数为 0
subscript_beyond_count 元素下标超过嵌套表或varray的最大值
subscript_outside_limit 使用嵌套表或 varray 时,将下标指定为负数
value_error 赋值时,变量长度不足以容纳实际数据
login_denied pl/sql 应用程序连接到 oracle 数据库时,提供了不正确的用户名或密码 确的用户名或密码
not_logged_on pl/sql 应用程序在没有连接 oralce 数据库的情况下访问数据 问数据
program_error pl/sql 内部问题,可能需要重装数据字典& pl./sql系统包 统包
rowtype_mismatch 主游标变量与 pl/sql 游标变量的返回类型不兼容
self_is_null 使用对象类型时,在 null 对象上调用对象方法
storage_error 运行 pl/sql 时,超出内存空间
sys_invalid_id 无效的 rowid 字符串
timeout_on_resource oracle 在等待资源时超时--自定义异常处理
CREATE OR REPLACE PROCEDURE stu_proc
(
--多个用逗号隔开
v_id IN NUMBER
) IS
--多个用分号隔开
v_max_id NUMBER;
v_name VARCHAR2(20);
v_raise EXCEPTION;
BEGIN
SELECT MAX(a.id) INTO v_max_id FROM student a;
IF v_id>v_max_id THEN
RAISE v_raise;
END IF;
SELECT o.sname INTO v_name FROM student o WHERE o.id=v_id;
dbms_output.put_line('学生名称为:'||v_name);
EXCEPTION
WHEN v_raise THEN
RAISE_APPLICATION_ERROR(-20010, 'v_id not exists!');
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20011, 'ERROR:不存在!');
END stu_proc;——————————————
——————————————————————————————————————————————————————————
Pl/SQL 编程的更多相关文章
- ORACLE PL/SQL编程详解
ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...
- Oracle数据库编程:PL/SQL编程基础
2.PL/SQL编程基础: PL/SQL块: declare 定义部分 begin 执行部分 exception 异 ...
- pl/sql编程
body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...
- [强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)
原文:[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) [强烈推荐]ORACLE PL/SQL编程详解之七: 程序包的创建与应用(聪明在于学习,天 ...
- ORACLE PL/SQL编程之八:把触发器说透
原文:ORACLE PL/SQL编程之八:把触发器说透 ORACLE PL/SQL编程之八: 把触发器说透 大家一定要评论呀,感谢!光发表就花了我将近一个下午. 本篇主要内容如下: 8.1 触发器类型 ...
- [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)
原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...
- ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)
原文:ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) ORACLE PL/SQL编程之六: 把过程与函数说透(穷追猛打,把根儿都拔起!) 继上篇:ORACLE P ...
- [推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)
原文:[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆) [推荐]ORACLE PL/SQL编程详解之三: PL/SQL流程控制语句(不给规则,不成方圆) ...
- [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到)
原文:[推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) [推荐]ORACLE PL/SQL编程之四: 把游标说透(不怕做不到,只怕想不到) 继上两篇:ORACLE PL ...
- 【强烈强烈推荐】《ORACLE PL/SQL编程详解》全原创(共八篇)--系列文章导航
原文:[强烈强烈推荐]<ORACLE PL/SQL编程详解>全原创(共八篇)--系列文章导航 <ORACLE PL/SQL编程详解> 系列文章目录导航 ——通过知识共享树立个人 ...
随机推荐
- Hadoop之YARN思维导图
- 帝国cms建站方法和知识点
帝国cms建站方法和知识点 1. 首先在帝国cms网站上下载模板系统.根据模板系统上的提示,将指定的目录文件放在指定的位置.然后进行安装.后台管理系统的命名设置.数据库的设置等等. 2. 安装完成 ...
- 获取汉字拼音&首字母
pinyin4j https://www.cnblogs.com/yjq520/p/7681537.html
- Springboot实体类转JSON报错Could not find acceptable representation & 设置访问项目根路径的默认欢迎页面
=================实体类转JSON报错的解决办法============= 之前在springmvc的时候也报过这个错,原因以及springmvc中解决办法参考:https://www ...
- 序列化 java.io.Serializable
1.序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来.虽然你可以用你自己的各种各样的方法来保存Object States,但是Java给你提供一种应该比 ...
- Zookeeper学习笔记4
开源客户端 ZkClient <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId ...
- Android 正则表达式验证手机号码
方案一:比较精准的判断手机段位,但是随着手机号段的增多要不断的修改正则 public boolean isPhoneNumber1(String phone) { String regExp = &q ...
- (转载)经典计算机视觉论文笔记——DeepFace\DeepID\DeepID2\DeepID3\FaceNet\VGGFace汇总
1. DeepFace:Closing the Gap to Human-Level Performance in Face Verification 最早将深度学习用于人脸验证的开创性工作.Face ...
- canner CMS 系统 (公司在台湾) https://www.canner.io/
canner CMS 系统 (公司在台湾) https://www.canner.io/ https://github.com/Canner/canner 一种创新的CMS构建方式,采用 Nodej ...
- MySQL查看表的索引【转】
查看表的索引: show index from table_name(表名) 结果列表中各字段的含义: · Non_unique 如果索引不能包括重复词,则为0.如果可以,则为1. · Key_nam ...