Oracle day 08 火推
来源:互联网 发布:类似招联好期贷的软件 编辑:程序博客网 时间:2024/05/18 13:10
GOTO语句
作用: 当前代码执行时, 跳转到标签位置 继续执行
标签定义语法格式: <<标签名>>
GOTO语法格式:goto 标签名
set serveroutput on;
declare
begin
dbms_output.put_line('一二三四五');
dbms_output.put_line('上山打老虎');
dbms_output.put_line('老虎没打到');
dbms_output.put_line('打到小松鼠');
goto a;
dbms_output.put_line('一二三四五');
dbms_output.put_line('一二三四五');
dbms_output.put_line('一二三四五');
dbms_output.put_line('一二三四五');
dbms_output.put_line('代码执行完毕');
<<a>>
end;
/
end语句前, 必须是一行可执行代码
我们上面的案例中, 最后一行是标签 , 程序报错, 说end出现的时机不对 !
如果我们的逻辑 确实已经完毕了 , 我们可以通过空行来实现最后一行代码的添加 !
NULL;
上述案例 改造后:
set serveroutput on;
declare
begin
dbms_output.put_line('一二三四五');
dbms_output.put_line('上山打老虎');
dbms_output.put_line('老虎没打到');
dbms_output.put_line('打到小松鼠');
goto a;
dbms_output.put_line('一二三四五');
dbms_output.put_line('一二三四五');
dbms_output.put_line('一二三四五');
dbms_output.put_line('一二三四五');
dbms_output.put_line('代码执行完毕');
<<a>>
NULL;
end;
/
使用goto模拟循环:
我们循环输出10首相同的打油诗
set serveroutput on;
declare
var_count number :=0;
begin
<<a>>
var_count := var_count+1;
dbms_output.put_line('一二三四五');
dbms_output.put_line('上山打老虎');
dbms_output.put_line('老虎没打到');
dbms_output.put_line('打到小松鼠');
if var_count!=10 then
goto a;
end if;
dbms_output.put_line('代码执行完毕,当前count为:'||var_count);
NULL;
end;
/
游标 对象
概念: Java中也存在结果集(游标) (ResultSet)
游标就是查询结果的容器
使用步骤与语法:
1. 声明一个游标
申明区中定义:
cursor 游标变量名称 is 查询语句;
2. 打开游标
在执行区操作:
open 游标变量名称;
3. 游标下移, 并提取一行数据
fetch 游标变量名称 into 变量;
--如果结果集中存在的数据格式为一列多行数据 , 可以赋值给基本数据类型 (number varchar2....)
--更多情况下, 我们是赋值给了 record类型
4. 关闭游标
close 游标变量名称;
--原因: 释放数据库连接句柄 , 连接句柄数量1024
--与Java中资源释放很像, 已经释放的资源 不可重复释放 !
定义一个游标, 结果集是s_emp表中的id,last_name,salary, 然后提取游标的前5条数据, 并打印到控制台 .
set serveroutput on;
declare
--声明游标
cursor s_emp_cursor is select id,last_name,salary from s_emp;
--定义record , 用来存储游标中取出的数据
type myemp is record(
id s_emp.id%type,
last_name s_emp.last_name%type,
salary s_emp.salary%type
);
--定义一个record类型的 变量
var_myemp myemp;
begin
--打开游标
open s_emp_cursor;
--循环取出前五条
for i in 1..5 loop
-- 游标向下移动一行, 并取出这行数据
fetch s_emp_cursor into var_myemp;
dbms_output.put_line('员工编号:'||var_myemp.id||',姓名:'||var_myemp.last_name||',月薪:'||var_myemp.salary);
end loop;
--关闭游标
close s_emp_cursor;
end;
/
通过游标%rowtype得到与游标属性一致的record变量
--改造上述的案例
set serveroutput on;
declare
--定义游标
cursor s_emp_cursor is select id,last_name,salary from s_emp;
--定义了一个与游标中属性一致的 record类型的变量
var_myemp s_emp_cursor%rowtype;
begin
--打开游标
open s_emp_cursor;
--循环取出游标前五条
for i in 1..5 loop
-- 游标向下移动一行, 并取出移动后行的数据赋值给var_myemp变量
fetch s_emp_cursor into var_myemp;
dbms_output.put_line('员工编号:'||var_myemp.id||',姓名:'||var_myemp.last_name||',月薪:'||var_myemp.salary);
end loop;
--关闭游标
close s_emp_cursor;
end;
/
通过游标获取 多个表格中的数据
查询s_dept表和s_region表 , 通过游标取出数据 , 并显示
set serveroutput on;
declare
cursor s_dr_cursor is select d.id dr_id,d.name dname,r.name rname from s_dept d,s_region r where d.region_id=r.id;
var_dr s_dr_cursor%rowtype;
begin
open s_dr_cursor;
fetch s_dr_cursor into var_dr;
dbms_output.put_line('部门编号:'||var_dr.dr_id||',部门名称:'||var_dr.dname||',所在地区:'||var_dr.rname);
close s_dr_cursor;
end;
游标属性
使用这些属性 可以完成循环遍历的操作
1. 游标变量%found
在游标下移后 提取到了新数据 ,则返回true , 否则返回false
2. 游标变量%notfound
在游标下移后, 未提取到新数据, 则返回true , 否则返回false
- 上述的属性, 使用的前提条件:
1. 游标必须是已经打开的 . 否则会报错 : 非法游标
2. 游标必须执行过下移操作(fetch) ,否则返回null
循环遍历游标
set serveroutput on;
declare
cursor s_dr_cursor is
select d.id dr_id,d.name dname,r.name rname from s_dept d,s_region r where d.region_id=r.id;
var_dr s_dr_cursor%rowtype;
begin
open s_dr_cursor;
loop
fetch s_dr_cursor into var_dr;
--如果上次提取数据失败, 则退出循环
exit when s_dr_cursor%notfound;
dbms_output.put_line('部门编号:'||var_dr.dr_id||',部门名称:'||var_dr.dname||',所在地区:'||var_dr.rname);
end loop;
close s_dr_cursor;
end;
练习: 改造上述循环游标案例, 使用while循环完成:
set serveroutput on;
declare
cursor s_dr_cursor is select d.id dr_id,d.name dname,r.name rname from s_dept d,s_region r where d.region_id=r.id;
var_dr s_dr_cursor%rowtype;
begin
open s_dr_cursor;
fetch s_dr_cursor into var_dr;
while s_dr_cursor%found loop
dbms_output.put_line('部门编号:'||var_dr.dr_id||',部门名称:'||var_dr.dname||',所在地区:'||var_dr.rname);
fetch s_dr_cursor into var_dr;
end loop;
close s_dr_cursor;
end;
- 1. 什么是循环条件
循环条件 指的是 当条件结果为true时, 循环继续!
- 2. 什么是退出循环条件
退出循环条件 指的是 当条件结果为true时, 循环结束
游标其它属性:
int[] arr = {1,2,3,4,5};
1. isopen : 判断游标是否打开 boolean类型, 无法参与字符串的拼接
2. rowcount: 获取当前游标所在的行的偏移量
set serveroutput on;
declare
cursor s_dr_cursor is select d.id dr_id,d.name dname,r.name rname from s_dept d,s_region r where d.region_id=r.id;
var_dr s_dr_cursor%rowtype;
begin
open s_dr_cursor;
fetch s_dr_cursor into var_dr;
while s_dr_cursor%found loop
dbms_output.put_line('部门编号:'||var_dr.dr_id||',部门名称:'||var_dr.dname||',所在地区:'||var_dr.rname);
-- 输出当前游标的打开状态
if s_dr_cursor%isopen then
dbms_output.put_line('当前游标打开');
end if;
-- 输出当前的偏移量
dbms_output.put_line('当前游标的偏移:'||s_dr_cursor%rowcount);
fetch s_dr_cursor into var_dr;
end loop;
close s_dr_cursor;
end;
智能循环 遍历游标
for循环遍历游标时
- 自动定义record变量
- 自动打开游标
- 自动提取数据赋值给record变量
- 自动关闭游标
set serveroutput on;
declare
cursor s_dr_cursor is select d.id dr_id,d.name dname,r.name rname from s_dept d,s_region r where d.region_id=r.id;
begin
for var_dr in s_dr_cursor loop
dbms_output.put_line('部门编号:'||var_dr.dr_id||',部门名称:'||var_dr.dname||',所在地区:'||var_dr.rname);
end loop;
end;
带参数的游标
一个游标在定义时, 可以指定游标打开时需要传递的参数 , 这个参数 可以应用到select语句中
格式
1. 定义游标时, 设置形式参数列表
cursor 游标变量名称(参数列表) is select语句;
2. 打开游标时, 传递实际参数
open 游标变量名称(参数);
练习:
--根据用户输入的员工编号, 查询一个员工的信息(id,last_name,salary):
set serveroutput on;
declare
cursor myemp_cursor(var_id number) is select id,last_name,salary from s_emp where id = var_id;
var_me myemp_cursor%rowtype;
var_id number;
begin
var_id := &请输入您要查询的员工的id;
open myemp_cursor(var_id);
fetch myemp_cursor info var_me;
dbms_output.put_line('员工的编号:'||var_me.id||',员工的姓名:'||var_me.last_name||',月薪:'||var_me.salary);
end;
/
使用智能循环时, 如何传递参数
之前我们说, for循环 会自动打开游标
--根据用户输入的员工编号, 查询比这个编号小的员工的信息(id,last_name,salary):
set serveroutput on;
declare
cursor myemp_cursor(var_id number) is select id,last_name,salary from s_emp where id < var_id;
var_id number;
begin
var_id := &请输入您要查询的员工的id;
for var_me in myemp_cursor(var_id) loop
dbms_output.put_line('员工的编号:'||var_me.id||',员工的姓名:'||var_me.last_name||',月薪:'||var_me.salary);
end loop;
end;
/
参考游标 ref cursor
参考游标在声明时, 无需指定select语句. 在打开游标时 根据需求,传入指定的SQL语句!
语法格式:
1. 先声明类型-申明区
type 自定义的名称(参考游标类名) is ref cursor;
2. 再声明游标的变量-申明区
变量名 自定义的名称(参考游标类名);
3. 打开游标-执行区
open 变量名 for '查询语句';
......
--------------------------
对比之前的操作:
1. 声明游标(得到变量)
申明区
cursor 变量名称 is 查询语句;
后续操作与普通游标一致
练习:
根据用户输入的操作类型, 来提示用户进行不同的操作查询:
set serveroutput on;
declare
--定义参考游标类型名
type mycursor is ref cursor;
-- 定义参考游标变量
var_mycursor1 mycursor;
--用来存储查询语句的字符串, 根据用户操作的不同, 赋予不同的查询语句
var_SQL varchar2(500);
--接收用户输入的操作类型
var_type number;
--接收用户输入的id参数
var_id number;
--定义变量
var_salary number;
var_name varchar2(25);
begin
dbms_output.put_line('欢迎进入公司管理系统: ');
dbms_output.put_line('请根据提示, 输入您的操作');
var_type := &查询员工信息输入1查询部门信息输入2;
if var_type=1 then
--查询用户信息
--1.提示用户输入要查询的员工id
var_id := &请输入您要查询的员工编号;
-- 根据用户输入的内容 拼接处一个查询语句,并赋值给var_SQL
var_SQL :='select salary from s_emp where id='||var_id;
-- 打开游标 并传递SQL语句
open var_mycursor1 for var_SQL;
-- 从游标中取出数据,并打印
fetch var_mycursor1 into var_salary;
dbms_output.put_line('您查询的员工的工资为:'||var_salary);
elsif var_type=2 then
--查询部门信息
--1. 提示用户输入要查询的部门编号
var_id := &请输入您要查询的部门编号;
-- 根据用户输入的部门编号, 来拼接SELECT语句
var_SQL := 'select name from s_dept where id='||var_id;
-- 打开游标, 传递SQL语句
open var_mycursor1 for var_SQL;
-- 从游标中取出数据 , 并打印
fetch var_mycursor1 into var_name;
dbms_output.put_line('您查询的部门名称为:'||var_name);
else
dbms_output.put_line('你是不是撒 , 脑袋有坑 !');
end if;
end;
/
NULL值的比较
在PL/SQL中 null值参与判断的操作中, 所有情况都不会匹配, 只能进入else块
注意不要混淆:
在SQL中, 对查询结果进行排序时, NULL值是最大的
set serveroutput on;
declare
var_a number;
var_b number;
begin
if var_a>var_b then
dbms_output.put_line('a大');
elsif var_a=var_b then
dbms_output.put_line('相等');
elsif var_a!=var_b then
dbms_output.put_line('不想等');
elsif var_a<var_b then
dbms_output.put_line('b大');
else
dbms_output.put_line('哈哈哈哈哈');
end if;
dbms_output.put_line('代码之行结束');
end;
/
异常处理
1. 编译时异常
语法格式的问题
2. 运行时异常
程序在运行时, 发生的一些异常
演示运行时异常的出现
set serveroutput on;
declare
var_last_name s_emp.last_name%type;
begin
select last_name into var_last_name from s_emp where id=-1;
dbms_output.put_line(var_last_name);
end;
/
出现了异常 "no data found"
异常处理格式:
begin
exception
--出现异常后, 这里的代码才会执行
when 异常类型1 then
--异常处理块
when 异常类型2 then
--异常处理块
...
when 异常类型n then
--异常处理块
when others then
--当上面的异常类型都不匹配时, 执行这里处理异常
end;
/
使用上述的格式, 处理上述代码的异常
set serveroutput on;
declare
var_last_name s_emp.last_name%type;
begin
select last_name into var_last_name from s_emp where id=-1;
dbms_output.put_line(var_last_name);
exception
when others then
dbms_output.put_line('出现了异常, 哈哈哈哈哈哈哈哈啊哈哈哈哈哈哈哈');
end;
/
异常被解决
--针对异常类型 进行处理
set serveroutput on;
declare
var_last_name s_emp.last_name%type;
begin
select last_name into var_last_name from s_emp where id=-1;
dbms_output.put_line(var_last_name);
exception
when no_data_found then
dbms_output.put_line('出现了异常, 数据找不到');
when others then
dbms_output.put_line('出现了异常, 哈哈哈哈哈哈哈哈啊哈哈哈哈哈哈哈');
end;
/
存储过程
把一组逻辑相关的SQL语句/PLSQL语句 组织到一起的一个代码结构 , 我们称之为过程 !
存储过程没有返回值 !
创建存储过程的语法格式:
create or replace procedure 名称(形参列表)
is
/*申明区*/
begin
end;
调用的语法格式:
方式1. call 过程名(实参列表);
方式2. exec 过程名(实参列表);
删除存储过程
drop procedure 存储过程名称;
练习
通过之前所学习的匿名块的编写, 编写一个案例, 比较两个数字的大小, 将大的数字输出 !
set serveroutput on;
declare
var_a number :=100;
var_b number :=-100;
begin
if var_a>var_b then
dbms_output.put_line('a大');
elsif var_a<var_b then
dbms_output.put_line('b大');
else
dbms_output.put_line('没有谁大谁小');
end if;
end;
根据上述的存储过程的语法格式, 将匿名块修改为存储过程, 并尝试调用
create or replace procedure mymax(var_a number,var_b number)
is
begin
if var_a>var_b then
dbms_output.put_line('a大');
elsif var_a<var_b then
dbms_output.put_line('b大');
else
dbms_output.put_line('没有谁大谁小');
end if;
end;
/
编译完毕上述的存储过程后, 调用
set serveroutput on;
call mymax(100,200);
drop procedure mymax;
给参数添加默认值
create or replace procedure mymax(var_a number:=500,var_b number:=1000)
is
begin
if var_a>var_b then
dbms_output.put_line('a大');
elsif var_a<var_b then
dbms_output.put_line('b大');
else
dbms_output.put_line('没有谁大谁小');
end if;
end;
/
set serveroutput on;
call mymax();
在匿名块中调用存储过程
set serveroutput on;
begin
mymax();
end;
/
通过desc 查看存储过程
desc mymax;
参数名 类型 In/Out 默认值
----- ------ ------ -------
VAR_A NUMBER IN DEFAULT(存在默认值)
VAR_B NUMBER IN DEFAULT(存在默认值)
In/Out:
参数的模式 , 默认为in , 指的是参数是否允许存储过程进行修改参数数据 !
取值:
- in: 默认模式, 表示参数只读
- out:表示参数只写
- in out: 可读可写
如果指定了参数的模式为 out/in out , 参数在传递时, 必须时变量!
改造上述的代码, 添加一个返回参数
mymax存储过程, 存在三个形式参数, 1. number 2.number 3. number
比较1和2的大小, 将大的数据 存储到3的位置
create or replace procedure mymax(var_a number:=500,var_b number:=1000,var_max out number)
is
begin
if var_a>var_b then
var_max := var_a;
elsif var_a<var_b then
var_max := var_b;
else
var_max := var_a;
end if;
end;
/
set serveroutput on;
declare
var_max number;
begin
mymax(100,101,var_max);
dbms_output.put_line('mymax返回了数据, 值为:'||var_max);
end;
练习:
1. mymax存储过程, 存在2个形式参数, 1. number 2.number
比较1和2的大小,
将大的数据 存储到2的位置
2. mymax存储过程, 存在2个形式参数, 1. number 2.number
比较1和2的大小,
将大的数据 存储到2的位置, 将两个数的和存储到1的位置
根据参数名称传递参数
语法格式:
参数名称=>传递的值
create or replace procedure mymax(var_a number:=500,var_b number:=1000,var_max out number)
is
begin
if var_a>var_b then
var_max := var_a;
elsif var_a<var_b then
var_max := var_b;
else
var_max := var_a;
end if;
end;
/
set serveroutput on;
declare
var_max number;
begin
mymax(var_a=>100,var_max);
dbms_output.put_line('mymax返回了数据, 值为:'||var_max);
end;
函数
public static void getXXX(int a,int b,HashMap<String,Object> data){
if(a>b){
data.put("max",a);
}else{
data.put("max",b);
}
}
阅读全文
0 0
- Oracle day 08 火推
- Oracle day02 火推
- Oracle day03 火推
- Oracle day06 火推
- Oracle数据库 day01 火推
- Oracle day07 PL/SQL 火推
- 2017暑期集训Day 9 递推
- J2ee day 2 oracle
- day-08
- spring mvc 08 火推
- Oracle数据库入门 基础知识day04 火推阳光笔记
- Oracle数据库入门 基础知识day05 火推阳光笔记
- jdbc day01 火推 function函数 Oracle JDBC连接步骤
- oracle的 date 和 day
- Day of 3 in Oracle
- DAY-01 Oracle数据库安装
- ZOJ 3785 What day is that day?【思维+递推循环节】
- Oracle数据库坏块及恢复-Day Day Up作品
- 使用MVP框架,retrofit结合Rxjava以及fresco加载图片,用recycleview实现
- Spring框架总结,控制反转(IOC),依赖注入(DI),面向切面编程(AOP)
- faster rcnn学习之rpn训练全过程
- 斐波那契数列性质总结
- 查询部门表中编码以074开头的城市公司,在字典维护
- Oracle day 08 火推
- WaitForSingleObject 事件处理
- gdb ulimit 生成core文件
- OpenStack Horizon开发环境
- EL表达式
- <转载>Java(17):Java常用数据结构及其特征解读
- jdbc day01 火推 function函数 Oracle JDBC连接步骤
- MATLAB中只显示坐标轴的左下段到右上端的部分
- 【LeetCode】448. Find All Numbers Disappeared in an Array