Oracle笔记4-pl/sql-分支/循环/游标/异常/存储/调用/触发器
一.pl/sql(Procedure Language/SQL)编程语言
1.概念
PL/SQL是Oracle数据库对SQL语句的扩展。在普通SQL语句的使用上增加了编程语言的特点,所以PL/SQL把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算。PL/SQL 只有 Oracle 数据库有。 MySQL 目前不支持 PL/SQL 的。
2.变量和常量
声明普通变量:
v_name varchar2(30) := 'tom'; (:=为赋值符号;=为比较符号,相当于java中的==);
声明引用型变量:
v_sal emp.sal%type := 100; 声明的v_sal变量与emp表中sal字段的类型一致;
声明记录型变量:
v_row emp%rowtype; 记录型变量相当于java中的resultset,用来存储整张表中的数据;
声明常量:
v_gender constant number(1) number(1) := 1;
3.分支语句
语法一:if ---then---end if;
语法二:if ---then---else---end if;
语法三:if ---then---elsif---then----else----end if;
举例:
--年龄小于18,显示未成年人,18-60,显示成年人,60以上显示老年人
declare
v_age number(8) :=#
begin
if v_age < 18 then
dbms_output.put_line('未成年人');
elsif v_age >= 18 and v_age <= 60 then
dbms_output.put_line('成年人');
else
dbms_output.put_line('老年人');
end if;
end;
4.循环语句
语法一:loop---exit when----end loop;
举例:
--输出1--100的数
declare
v_num number(8) := 1;
begin
loop
exit when v_num > 100;
dbms_output.put_line(v_num);
v_num := v_num + 1;
end loop;
end;
语法二:while---loop----end loop;
declare
v_num number(8) := 1;
begin
while v_num <= 100 loop
dbms_output.put_line(v_num);
v_num := v_num + 1;
end loop;
end;
语法三:for---in 起始值..终止值---loop---end loop;
declare
v_num number(8) := 1;
begin
for v_num in 1 .. 100 loop
dbms_output.put_line(v_num);
end loop;
end;
5.游标(cursor)
作用:用来接收多条数据结果,相当于java中的ResultSet
语法:cursor 游标名称 is sql 查询语句;
使用:
open 游标名称
loop
fetch 游标名称 into 记录型变理
exit when 游标名称%notfound;
逻辑处理
end loop;
close 游标名称;
举例:
--打印emp表的所有信息
DECLARE
CURSOR c_emp IS SELECT * FROM emp;
v_row emp%ROWTYPE;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO v_row;
EXIT WHEN c_emp%NOTFOUND;
dbms_output.put_line(v_row.ename||'--'||v_row.job);
END LOOP;
CLOSE c_emp;
END;
--带参数的游标
DECLARE
CURSOR c_emp(v_no1 NUMBER, v_no2 NUMBER) IS SELECT * FROM emp WHERE deptno = v_no1 OR deptno = v_no2;
v_row emp%ROWTYPE;
BEGIN
OPEN c_emp(10,20);--传入部门编号deptno
LOOP
FETCH c_emp INTO v_row;
EXIT WHEN c_emp%NOTFOUND;
dbms_output.put_line(v_row.ename||'=='||v_row.job);
END LOOP;
CLOSE c_emp;
END;
6.异常
exception---when----then
--预定义异常
DECLARE
v_num NUMBER(3);
BEGIN
v_num := 10000;
EXCEPTION
WHEN value_error THEN
v_num := 999;
dbms_output.put_line(v_num);
END;
--自定义异常
DECLARE
V_AGE NUMBER(8) := &NUM;
EXC_AGE EXCEPTION; --声明异常
BEGIN
IF V_AGE > 150 THEN
RAISE EXC_AGE;
END IF;
EXCEPTION
WHEN EXC_AGE THEN
RAISE_APPLICATION_ERROR(-20001, 'illegal age');
END;
二.存储过程
概念:一段被命名的plsql,预编译到了数据库中
语法:
create or replace procedure 存储过程名字(参数1 [in]/out 数据类型)
as | is
begin
end;
例子1:
--存储过程,打印指定员工的年薪
create or replace procedure pro_emp_sal(v_no number) is
v_sal number(8, 2);
begin
select sal * 12 + nvl(comm, 0) into v_sal from emp where empno = v_no;
dbms_output.put_line(v_sal);
end;
--方法一调用存储过程
call pro_emp_sal(7788);
--方法二调用存储过程
begin
pro_emp_sal(7788);
end;
例子2:带out参数的存储过程
CREATE OR REPLACE PROCEDURE pro_emp_sal2(v_no NUMBER, v_yearsal OUT NUMBER) IS
BEGIN
SELECT sal*12 + NVL(comm,0) INTO v_yearsal FROM emp WHERE empno = v_no;
END;
--只能使用方式二调用
DECLARE
v_sal NUMBER(8,2);
BEGIN
pro_emp_sal2(7788,v_sal);
dbms_output.put_line(v_sal);
END;
三.存储函数
--存储函数
CREATE OR REPLACE FUNCTION fun_emp_sal(v_no NUMBER)
RETURN NUMBER
IS
v_sal NUMBER(8,2);
BEGIN
SELECT sal*12+NVL(comm,0) INTO v_sal FROM emp WHERE empno = v_no;
RETURN v_sal;
END;
--使用存储函数
BEGIN
dbms_output.put_line(fun_emp_sal(7788));
END;
注:存储过程和存储函数的区别
1、语法不同
2、使用场景:一般存储函数多被存储过程使用,存储过程一般使用在项目和项目之间的数据交互
3、存储函数可以直接在sql中使用,而存储过程不能
select ename,sal,func_emp_sal(empno) from emp;
四.使用jdbc调用存储过程和存储函数
1.BaseDao用于加载驱动和获取连接
2.ProcedureDao用于调用存储过程
3.TestDao用于测试
举例:
1.BaseDao用于加载驱动和获取连接
public class BaseDao {
//加载驱动
static{
try {
Class.forName("oracle.jdbc.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConn() throws SQLException{
String url="jdbc:oracle:thin:@192.168.92.8:1521:orcl";
String user="qin";
String password="qin";
return DriverManager.getConnection(url, user, password);
}
public static void closeAll(ResultSet rs,Statement stmt,Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
2.ProcedureDao用于调用存储过程
public class ProcedureDao {
public static Long getSal(Long v_no){
Connection conn = null;
CallableStatement stmt=null;
Long yearsal=0l;
try {
conn=BaseDao.getConn();
stmt = conn.prepareCall("call pro_emp_sal2(?,?)");//调用存储过程
stmt.setLong(1, v_no);
stmt.registerOutParameter(2, OracleTypes.NUMBER); //指定参数的数据类型
stmt.execute();
yearsal = stmt.getLong(2);
} catch (SQLException e) {
e.printStackTrace();
}
return yearsal;
}
}
3.TestDao用于测试
public class TestDao {
public static void main(String[] args) {
CursorDao.getEmp(10l);
}
}
五.触发器
1.--创建添加数据引发操作的触发器
CREATE OR REPLACE TRIGGER tri_add_emp
AFTER
INSERT ON emp
BEGIN
dbms_output.put_line('增加了一条数据');
END;
--增加一条数据,看是否会触发
INSERT INTO emp(empno,ename,deptno) VALUES(1,'tom',10);
2.--系统时间引发的触发器
CREATE OR REPLACE TRIGGER tri_emp
BEFORE
DELETE OR UPDATE OR INSERT
ON emp
FOR EACH ROW
DECLARE
v_dateStr VARCHAR2(20);
BEGIN
SELECT to_char(SYSDATE,'yyyy-mm-dd') INTO v_dateStr FROM dual;
IF v_dateStr = '2017-09-20' THEN
raise_application_error(-20002,'今天系统维护');
END IF;
END;
--测试是否能引发触发器
INSERT INTO emp(empno,ename,deptno) VALUES (3,'jerry',10);
六.误删除数据恢复语句
create table tableName_bak
as
select * from tableName as of TIMESTAMP to_timestamp('20081126 103435','yyyymmdd hh24miss');
Oracle笔记4-pl/sql-分支/循环/游标/异常/存储/调用/触发器的更多相关文章
- Oracle数据库之PL/SQL程序设计简介
PL/SQL程序设计简介 一.什么是PL/SQL? PL/SQL是 Procedure Language & Structured Query Language 的缩写. ORACLE的SQL ...
- 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》
本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...
- Oracle数据库之PL/SQL包
Oracle数据库之PL/SQL包 1. 简介 包(PACKAGE)是一种数据对象,它是一组相关过程.函数.变量.常量和游标等PL/SQL程序设计元素的组合,作为一个完整的单元存储在数据库中,用名称来 ...
- Oracle数据库之PL/SQL异常处理
Oracle数据库之PL/SQL异常处理 异常指的是在程序运行过程中发生的异常事件,通常是由硬件问题或者程序设计问题所导致的. PL/SQL程序设计过程中,即使是写得最好的程序也可能会遇到错误或未预料 ...
- Oracle数据库之PL/SQL流程控制语句
Oracle数据库之PL/SQL流程控制语句 在任何计算机编程语言(如C,Java,C#等)都有各种流程控制语句,同样,在PL/SQL中也存在这样的流程控制结构. 几种常见的流程控制结构: 一.条件结 ...
- [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)
原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...
- oracle系列(四)PL/SQL
过程,函数,触发器是PL/SQL编写的,存储在oracle中的.PL/SQL是非常强大的数据库过程语言. PL/SQL优点:性能,模块化,网络传输量,安全性缺点:移植性不好 简单分类:块:过程,函数, ...
- oracle数据库之PL/SQL 块结构和组成元素
一.PL/SQL 块 (一)PL/SQL 程序由三个块组成,即声明部分.执行部分.异常处理部分 PL/SQL 块的结构如下: 1.DECLARE /* 声明部分: 在此声明 PL/SQL 用到的变量, ...
- Oracle学习2 视图 索引 sql编程 游标 存储过程 存储函数 触发器
---视图 ---视图的概念:视图就是提供一个查询的窗口,来操作数据库中的数据,不存储数据,数据在表中. ---一个由查询语句定义的虚拟表. ---查询语句创建表 create table emp a ...
随机推荐
- 二维树状数组总结&&【洛谷P4514】 上帝造题的七分钟
P4514 上帝造题的七分钟 题目描述 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了00的n×mn×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b)(a,b),右下 ...
- 树链剖分【洛谷P3833】 [SHOI2012]魔法树
P3833 [SHOI2012]魔法树 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节 ...
- 关于如何在Windows下测交互题
这里的交互题指的NOI风格的交互题,即交互库 codeforces风格的交互题...只能自己实现评测插件了 使用Cena,Lemon没有附加文件功能不能评测交互题 在编译选项g++编译命令源文件中加入 ...
- CF1076D Edge Deletion 最短路径树+bfs
题目描述 You are given an undirected connected weighted graph consisting of n n n vertices and m m m edg ...
- kuangbin专题十六 KMP&&扩展KMP HDU3347 String Problem(最小最大表示法+kmp)
Give you a string with length N, you can generate N strings by left shifts. For example let consider ...
- springcloud系列二 搭建注册中心启动
创建modul 然后就创建完成了 添加yml文件: server: port: eureka: client: register-with-eureka: false #单机版建议设置为false,设 ...
- 二叉树的遍历 &【NOIP2001普及组】& 洛谷 P1030 求先序排列
题目链接 https://www.luogu.org/problemnew/show/P1030 模板题 先讲一下二叉树的遍历 二叉树的遍历 分类 性质 求法 分为三类: 先序遍历(PreOrder) ...
- bootstrap-table 选择行,并且获得选中行的所有数据内容
html代码如下: <table id="table" data-toggle="table" th:attr="data-url=@{/vie ...
- FileWriter 中午乱码
解决办法 BufferedWriter writer = new BufferedWriter (new OutputStreamWriter (new FileOutputStream (fil ...
- Windows任务计划创建计划,定时执行PowerShell命令
[环境介绍] 操作系统:Windows Server 2012 R2,64位操作系统 PowerShell版本:PowerShell 1.0 脚本位置:C:\BackUp.ps1 启动目录:C:\Wi ...