Pl/SQL 编程

一:前言

二:Pl/Sql 概述

二     ——  1: Pl/Sql块结构

declare
--声明部分,可选
begin
--执行部分,必须
[exception]
--异常处理部分,可选
end

 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:多行注释

 set serveroutput on;      /*在服务器端 输出结果*/
declare
Num_sal number;
Var_ename varchar2(20);
begin
/*检索指定的值并储存到变量中*/
select e.ename,e.sal into Var_ename,Num_sal from emp e where empno=7839; --检索指定的值并储存到变量中
dbms_output.put_line(Var_ename||'工资是'||Num_sal);
end;
/

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

 SQL> set serveroutput on
SQL> declare
2 age int:=55;/*定义整型变量并赋值*/
3 begin
4 if age >=56 then
5 dbms_output.put_line('您可以申请退休了!');
6 else
7 dbms_output.put_line('您小于56岁,不可以申请退休了!');
8 end if;
9 end;
10 / 您小于56岁,不可以申请退休了! PL/SQL procedure successfully completed

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

 set serveroutput on
declare
sum_i int:=0; /*定义整数变量,存储整数和*/
i int:=0;/*定义整数变量 储存自然数*/
begin
loop /*循环累加自然数*/
i:= i+1; /*得出自然数*/
sum_i := sum_i + i;/*计算前n个自然数的和*/
exit when i=100; /*当循环100次后,程序退出循环体*/
end loop;
dbms_output.put_line('前100个自然数的和是'||sum_i);/*计算前100个自然数的和*/
end;
/

四    ——2_____2: while 语句

 set serveroutput on
declare
sum_i int:=0;/*定义变量并赋值*/
i int :=0;/*定义变量并赋值*/
begin
while i<99 loop
i:=i+1;/*当i的值等于100时,程序退款while循环*/
sum_i :=sum_i +i;/*计算前n个自然数的和*/
end loop;
dbms_output.put_line('前100个自然数的和是'||sum_i);/*计算前100个自然数的和*/
end;
/

四    ——2_____3: for 语句

 set serveroutput on
declare
sum_i int :=0;/*定义变量并赋值*/
begin
for i in 1..100 loop /*遍历前100个自然数*/
if mod(i,2)=0 then /*判断是否为偶数*/
sum_i:=sum_i +i; /*计算偶数和*/
end if;
end loop;
dbms_output.put_line('前100个自然数的和是'||sum_i);/*计算前100个自然数的和*/
end;
/

五 :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 编程的更多相关文章

  1. ORACLE PL/SQL编程详解

    ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...

  2. Oracle数据库编程:PL/SQL编程基础

    2.PL/SQL编程基础: PL/SQL块:        declare        定义部分        begin        执行部分        exception        异 ...

  3. pl/sql编程

    body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...

  4. [强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)

    原文:[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) [强烈推荐]ORACLE PL/SQL编程详解之七: 程序包的创建与应用(聪明在于学习,天 ...

  5. ORACLE PL/SQL编程之八:把触发器说透

    原文:ORACLE PL/SQL编程之八:把触发器说透 ORACLE PL/SQL编程之八: 把触发器说透 大家一定要评论呀,感谢!光发表就花了我将近一个下午. 本篇主要内容如下: 8.1 触发器类型 ...

  6. [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)

    原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...

  7. ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)

    原文:ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) ORACLE PL/SQL编程之六: 把过程与函数说透(穷追猛打,把根儿都拔起!)   继上篇:ORACLE P ...

  8. [推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)

    原文:[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆) [推荐]ORACLE PL/SQL编程详解之三: PL/SQL流程控制语句(不给规则,不成方圆) ...

  9. [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到)

    原文:[推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) [推荐]ORACLE PL/SQL编程之四: 把游标说透(不怕做不到,只怕想不到) 继上两篇:ORACLE PL ...

  10. 【强烈强烈推荐】《ORACLE PL/SQL编程详解》全原创(共八篇)--系列文章导航

    原文:[强烈强烈推荐]<ORACLE PL/SQL编程详解>全原创(共八篇)--系列文章导航 <ORACLE PL/SQL编程详解> 系列文章目录导航 ——通过知识共享树立个人 ...

随机推荐

  1. Hadoop之YARN思维导图

  2. 帝国cms建站方法和知识点

    帝国cms建站方法和知识点 1.  首先在帝国cms网站上下载模板系统.根据模板系统上的提示,将指定的目录文件放在指定的位置.然后进行安装.后台管理系统的命名设置.数据库的设置等等. 2.  安装完成 ...

  3. 获取汉字拼音&首字母

    pinyin4j https://www.cnblogs.com/yjq520/p/7681537.html

  4. Springboot实体类转JSON报错Could not find acceptable representation & 设置访问项目根路径的默认欢迎页面

    =================实体类转JSON报错的解决办法============= 之前在springmvc的时候也报过这个错,原因以及springmvc中解决办法参考:https://www ...

  5. 序列化 java.io.Serializable

    1.序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来.虽然你可以用你自己的各种各样的方法来保存Object States,但是Java给你提供一种应该比 ...

  6. Zookeeper学习笔记4

    开源客户端 ZkClient <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId ...

  7. Android 正则表达式验证手机号码

    方案一:比较精准的判断手机段位,但是随着手机号段的增多要不断的修改正则 public boolean isPhoneNumber1(String phone) { String regExp = &q ...

  8. (转载)经典计算机视觉论文笔记——DeepFace\DeepID\DeepID2\DeepID3\FaceNet\VGGFace汇总

    1. DeepFace:Closing the Gap to Human-Level Performance in Face Verification 最早将深度学习用于人脸验证的开创性工作.Face ...

  9. canner CMS 系统 (公司在台湾) https://www.canner.io/

    canner  CMS 系统 (公司在台湾) https://www.canner.io/ https://github.com/Canner/canner 一种创新的CMS构建方式,采用 Nodej ...

  10. MySQL查看表的索引【转】

    查看表的索引: show index from table_name(表名) 结果列表中各字段的含义: · Non_unique 如果索引不能包括重复词,则为0.如果可以,则为1. · Key_nam ...