【Oracle】Oracle编程PLSQL

Oracle编程

一、PL/SQL

1、PL/SQL概述

PL/SQL(Procedure Language/SQL)是 Oracle 对 sql 语言的过程化扩展,使 SQL 语言具有过程处理能力。

基本语法结构

[declare -- 声明变量
]begin-- 代码逻辑 [exception-- 异常处理
]end;
2、变量
1)变量的声明与赋值
-- 声明变量
变量名 类型(长度);-- 变量赋值
变量名:=变量值;
2)直接赋值

声明变量水费单价、水费字数、吨数、金额。

对水费单价、字数、进行赋值 。吨数根据水费字数换算,规则为水费字数除以

1000,并且四舍五入,保留两位小数。计算金额,金额 = 单价 * 吨数。

输出:单价、数量和金额。

declarev_price number(10,2);	-- 水费单价v_usenum number; 		-- 水费字数v_usenum2 number(10,2);	-- 吨数v_money number(10,2);	-- 金额 
begin-- 变量赋值v_price:=2.45;v_usenum:=8012;-- 字数换算为吨数v_usenum2:= round( v_usenum/1000,2 );-- 计算金额v_money:=round(v_price*v_usenum2,2);-- 文字的输出dbms_output.put_line('金额:'||v_money); 
end;
2)select into 赋值
-- select into 语法
select 列名 into 变量名 from 表名 where 条件

select into 结果必须是一条记录 ,有多条记录和没有记录都会报错

declarev_price number(10,2);	-- 单价v_usenum number;		-- 水费字数v_num0 number;			-- 上月字数v_num1 number;			-- 本月字数v_usenum2 number(10,2);	-- 使用吨数v_money number(10,2);	-- 水费金额
begin-- 对单价进行赋值v_price:=3.45;-- select into赋值select usenum,num0,num1 into v_usenum,V_num0,V_num1 from T_ACCOUNT where year='2012' and month='01' and owneruuid=1;-- 字数换算v_usenum2:= round(v_usenum/1000,2);-- 计算金额v_money:=v_price*v_usenum2;-- 文字的输出DBMS_OUTPUT.put_line(''金额:'||v_money||'上月字数:'||v_num0||'本月字数'||v_num1);
end;
3、属性类型
1)%TYPE 引用型

引用某表某的字段类型

对于不知道表内类型的数据,可以直接获取表内列的类型

declarev_price number(10,2);				-- 单价v_usenum T_ACCOUNT.USENUM%TYPE;		-- 水费字数v_num0  T_ACCOUNT.NUM0%TYPE;		-- 上月字数v_num1 T_ACCOUNT.NUM1%TYPE;			-- 本月字数v_usenum2 number(10,2);				-- 使用吨数v_money number(10,2);				-- 水费金额
2)%ROWTYPE 记录型

标识某个表的记录类型

一个记录型代表一行数据,类似java编程的实体类

declarev_price number(10,2);			-- 单价v_account T_ACCOUNT%ROWTYPE;	-- 台账行的记录型v_usenum2 number(10,2);			-- 使用吨数v_money number(10,2);			-- 水费金额
begin-- 对单价进行赋值v_price:=3.45;-- select into赋值select * into v_account from T_ACCOUNT where year='2012' and month='01' and owneruuid=1;-- 使用吨数v_usenum2:= round(v_account.usenum/1000,2);-- 计算金额v_money:=v_price*v_usenum2;-- 文字的输出  DBMS_OUTPUT.put_line('金额:'||v_money);
end;
4、异常(例外)

发生异常后,语句将停止执行,控制权转移到 PL/SQL 块的异常处理部分

  • 预定义异常:Oracle预先定义的异常
    • NO_DATA_FOUND:使用 select into 未返回行
    • TOO_MANY_ROWS:执行 select into 时,结果集超过一行
  • 用户定义异常:用户定义异常,通过 RAISE 语句显式引发
-- 异常语法结构exceptionwhen 异常类型 then异常处理逻辑
declarev_price number(10,2);			-- 水费单价v_usenum T_ACCOUNT.USENUM%type; -- 水费字数v_usenum2 number(10,3);			-- 吨数v_money number(10,2);			-- 金额 begin-- 水费单价v_price:=2.45;-- select into赋值select usenum into v_usenum from T_ACCOUNTwhere owneruuid=1 and year='2012' and month='01';-- 字数换算为吨数v_usenum2:= round( v_usenum/1000,3);-- 计算金额v_money:=round(v_price*v_usenum2,2);-- 信息输出dbms_output.put_line('金额:'||v_money);-- 异常处理
exceptionwhen NO_DATA_FOUND thendbms_output.put_line('未找到数据');when TOO_MANY_ROWS thendbms_output.put_line('查询条件有误,返回多条信息');
end;
5、条件判断
-- 1、if
if 条件 then代码;
end if;-- 2、if else
if 条件 then代码;
else代码;
end if;-- 3、if elif eles
if 条件 then代码;
elsif 条件 then代码;
else代码;
end if;

设置三个等级的水费。 5 吨以下 2.45 元/吨,5 吨到 10 吨部分 3.45 元/吨,超过 10 吨部分 4.45 元/吨

根据使用水费的量来计算阶梯水费。

declarev_price1 number(10,2);		-- 不足 5 吨的单价v_price2 number(10,2);		-- 超过 5 吨不足 10 吨单价v_price3 number(10,2);		-- 超过 10 吨单价v_account T_ACCOUNT%ROWTYPE;-- 记录型v_usenum2 number(10,2);		-- 使用吨数v_money number(10,2);		-- 水费金额
begin-- 单价赋值v_price1:=2.45;v_price2:=3.45;v_price3:=4.45;-- select into赋值select * into v_account from T_ACCOUNT where year='2012' and month='01' and owneruuid=1;-- 使用吨数v_usenum2:= round(v_account.usenum/1000,2);-- 计算金额(阶梯水费)-- 第一个阶梯if v_usenum2<=5 thenv_money:=v_price1*v_usenum2;-- 第二个阶梯elsif v_usenum2>5 and v_usenum2<=10 then v_money:=v_price1*5+v_price2*(v_usenum2-5); -- 第三个阶梯elsev_money:=v_price1*5+v_price2*5+v_price3*(v_usenum2-10);end if;-- 信息输出DBMS_OUTPUT.put_line('金额:'||v_money);-- 异常处理
exceptionwhen NO_DATA_FOUND thenDBMS_OUTPUT.put_line('没有找到数据');when TOO_MANY_ROWS thenDBMS_OUTPUT.put_line('返回的数据有多行');
end;
6、循环
1)loop无条件循环
loop代码exit when 退出条件;
end loop;
-- 输出1至100
declarev_num number:=1;
begin loopdbms_output.put_line(v_num);v_num:=v_num+1;exit when v_num>100;end loop; 
end;
2)while条件循环
while 条件
loop代码
end loop;
-- 输出1至100
declarev_num number:=1;
begin while v_num<=100loopdbms_output.put_line(v_num);v_num:=v_num+1;end loop; 
end;
3)for循环
for 变量 in 起始值 .. 终止值
loop代码
end loop;
-- 输出1至100
beginfor v_num in 1 .. 100loopdbms_output.put_line(v_num); end loop;
end;
7、游标
1)游标概述

存放 SQL 语句执行的结果集

2)游标的语法
-- 声明游标
cursor 游标名称 is SQL语句;-- 使用游标
open 游标名称
loopfetch 游标名称 into 变量;exit when 游标名称%notfound;
end loop;
close 游标名称

打印业主类型为 1 的价格表

declare-- 价格的行对象v_pricetable T_PRICETABLE%rowtype;-- 定义游标cursor cur_pricetable is select * from T_PRICETABLE where ownertypeid=1;
begin-- 打开游标open cur_pricetable;loop-- 提取游标到变量fetch cur_pricetable into v_pricetable;-- 当游标到最后一行下面退出循环exit when cur_pricetable%notfound;-- 打印数据dbms_output.put_line('价格:'||v_pricetable.price); end loop;-- 关闭游标close cur_pricetable;
end ;
3)带参数的游标

条件值有可能是在运行时才能决定的

类似于java的传参

declare-- 价格的行对象v_pricetable T_PRICETABLE%rowtype;-- 定义游标cursor cur_pricetable(v_ownertype number) is select * from T_PRICETABLE where ownertypeid=v_ownertype;
begin-- 打开游标open cur_pricetable(1);loop-- 提取游标到变量fetch cur_pricetable into v_pricetable;-- 当游标到最后一行下面退出循环exit when cur_pricetable%notfound;-- 打印数据dbms_output.put_line('价格:'||v_pricetable.price); end loop;-- 关闭游标close cur_pricetable;
end ;
4)for 循环提取游标值
declare-- 定义游标cursor cur_pricetable(v_ownertypeid number) is select * from T_PRICETABLE where ownertypeid=v_ownertypeid;
begin-- for循环for v_pricetable in cur_pricetable(3)loop dbms_output.put_line('价格:'||v_pricetable.price); end loop; 
end ;

二、存储函数

1、存储函数概述

存储函数又称为自定义函数。可以接收一个或多个参数,返回一个结果。

2、存储函数语法结构
create [ or replace ] function 函数名称
(参数名称 参数类型, 参数名称 参数类型, ...)
return 结果变量数据类型
is变量声明部分;
begin逻辑部分;return 结果变量;
[exception 异常处理部分]
end;
3、案例

创建存储函数,根据地址 ID 查询地址名称

create function fn_getaddress(v_id number) 
return varchar2
isv_name varchar2(30);
beginselect name into v_name from t_address where id=v_id;return v_name;
end;
-- 测试函数
select fn_getaddress(3) from dual-- 函数在子查询的应用
select id 编号,name 业主名称,fn_getaddress(addressid) 地址 from t_owners

三、存储过程

1、存储过程概述

存储过程没有return,但是可以通过传出函数,传出多个返回值

应用程序可以调用存储过程,执行相应的逻辑,对业务逻辑的封装。

与MVC框架的思想冲突

效率比MVC框架高

2、存储过程语法结构
create [ or replace ] procedure 存储过程名称
(参数名 类型, 参数名 类型, 参数名 类型)
is|as变量声明部分;
begin逻辑部分;
[exception 异常处理部分;]
end;

参数只指定类型,不指定长度

过程参数的三种模式:

  • IN :传入参数(默认)
  • OUT :传出参数 ,主要用于返回程序运行结果
  • IN OUT :传入传出参数
3、案例
1)不带传出参数的存储过程
-- 创建
create or replace procedure pro_owners_add 
(v_name varchar2,v_addressid number,v_housenumber varchar2, v_watermeter varchar2,v_type number
)
is
begininsert into T_OWNERS values( seq_owners.nextval,v_name,v_addressid,v_housenumber,v_watermeter,sysdate,v_type);commit;
end;-- 调用
-- 1、call
call pro_owners_add('赵伟',1,'999-3','132-7',1);
-- 2、begin end
beginpro_owners_add('赵伟',1,'999-3','132-7',1);
end;
// JDBC 调用存储过程
public static void add(Owners owners){java.sql.Connection conn = null;java.sql.CallableStatement stmt = null;try {conn = BaseDao.getConnection();stmt = conn.prepareCall("{call pro_owners_add(?,?,?,?,?)}");stmt.setString(1, owners.getName());stmt.setLong(2, owners.getAddressid());stmt.setString(3, owners.getHousenumber());stmt.setString(4, owners.getWatermeter());stmt.setLong(5, owners.getOwnertypeid());stmt.execute();} catch (SQLException e) {e.printStackTrace();} finally {BaseDao.closeAll(null, stmt, conn);}
}
2)带传出参数的存储过程
-- 创建
create or replace procedure pro_owners_add 
(v_name varchar2,v_addressid number,v_housenumber varchar2, v_watermeter varchar2,v_type number,v_id out number -- 传出参数
)
is 
beginselect seq_owners.nextval into v_id from dual;insert into T_OWNERS values(v_id,v_name,v_addressid,v_housenumber,v_watermeter,sysdate,v_type);commit;
end;-- 调用
declarev_id number;
beginpro_owners_add('王旺旺',1,'922-3','133-7',1,v_id);DBMS_OUTPUT.put_line('增加成功,ID:'||v_id);
end;
// JDBC 调用存储过程
public static long add(Owners owners) {long id = 0;java.sql.Connection conn = null;java.sql.CallableStatement stmt = null;try {conn = BaseDao.getConnection();stmt = conn.prepareCall("{call pro_owners_add(?, ?,?,?,?,?)} ");stmt.setString(1, owners.getName());stmt.setLong(2, owners.getAddressid());stmt.setString(3, owners.getHousenumber());stmt.setString(4, owners.getWatermeter());stmt.setLong(5, owners.getOwnertypeid());// 册传出参数类型:表明第六个参数是传出参数stmt.registerOutParameter(6, OracleTypes.NUMBER);// 执行stmt.execute();// 执行后传出参数id = stmt.getLong(6);} catch (SQLException e) {e.printStackTrace();} finally {BaseDao.closeAll(null, stmt, conn);}return id;
}

四、触发器

1、触发器概述

触发器是一个与表相关联的、存储的PL/SQL程序。

每当一个特定的操作,Oracle自动地执行触发器中定义的语句序列。

触发器可用于

  • 数据确认:录入的合法性验证
  • 实施复杂的安全性检查
  • 做审计,跟踪表上所做的数据操作等
  • 数据的备份和同步

触发器分类

  • 前置触发器(BEFORE):sql执行前执行触发器,可以修改sql执行的值
  • 后置触发器(AFTER):sql执行后执行触发器
2、创建触发器
create [or replace] trigger 触发器名before|after[delete][[or] insert] [[or] update[of 列名]]on 表名[for each row][when(条件)]
declare变量
begin代码
end;
  • FOR EACH ROW :作用是标注此触发器是行级触发器,不标注为语句级触发器
    • 行级触发器:每影响一行触发一次
    • 语句级触发器:每个语句只触发一次

在触发器中触发语句与伪记录变量的值

触发语句:old(修改前的行数据):new(修改后的行数据)
insert所有字段都是空(null)将要插入的数据
update更新以前该行的值更新后的值
delete删除以前该行的值所有字段都是空(null)
3、案例
1)前置触发器

当用户输入本月累计表数后,自动计算出本月使用数

CREATE OR REPLACE TRIGGER tri_account_update_num1before UPDATE OF num1 ON t_account FOR each ROW
DECLARE
BEGIN: new.usenum :=: new.num1 -: new.num0;
END;
2)后置触发器

当用户修改了业主信息表的数据时记录修改前与修改后的值

CREATE TRIGGER tri_owners_logafterUPDATE OF nameON t_ownersFOR each ROW
DECLARE
BEGININSERT INTO t_owners_log VALUES(SYSDATE,: old.id,: old.name,: new.name);
END;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/617306.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos7下升级openssh9.4p1及openssl1.1.1v版本

背景&#xff1a;客户服务器扫描出一些漏洞&#xff0c;发现和版本有关&#xff0c;漏洞最高的版本是9.3p2&#xff0c;所以我们安装一个openssh9.4p1版本及openssl1.1.1v版本 虽然我们进行了镜像备份&#xff0c;为了安全先安装telnet以防止升级失败无法通过ssh连接服务器 一…

【会议征稿通知】第二届数字化经济与管理科学国际学术会议(CDEMS 2024)

第二届数字化经济与管理科学国际学术会议&#xff08;CDEMS 2024&#xff09; 2024 2nd International Conference on Digital Economy and Management Science&#xff08;CDEMS 2024&#xff09; 2024年第二届数字经济与管理科学国际会议(CDEMS 2024) 定于2023年4月26-28日…

如何使用统计鸟网站统计分析网站流量来源?

统计鸟官网地址&#xff1a;https://www.tongjiniao.com/ 站长必备&#xff01;网站数据统计&#xff0c;流量监测平台 提供网站数据统计分析、搜索关键词、流量访问来源等服务 深入分析用户点击习惯&#xff0c;为智能化运营网站提供更好的用户体验 目录 一、注册账号信息 二…

基于博弈树的开源五子棋AI教程[3 极大极小搜索]

基于博弈树的开源五子棋AI教程[3 极大极小搜索] 引子极大极小搜索原理alpha-beta剪枝负极大搜索尾记 引子 极大极小搜索是博弈树搜索中最常用的算法&#xff0c;广泛应用于各类零和游戏中&#xff0c;例如象棋&#xff0c;围棋等棋类游戏。算法思想也是合乎人类的思考逻辑的&a…

Flask+ Dependency-injecter+pytest 写测试类

最近在使用这几个在做项目&#xff0c;因为第一次用这个&#xff0c;所以不免有些问题。总结下踩的坑 1.测试类位置 首先测试类约定会放在tests里面&#xff0c;不然有可能发生引入包的问题&#xff0c;会报错某些包找不到。 2. 测试类依赖注入 这里我就用的真实的数据库操作…

Js--数组(三)

1.什么是数组&#xff1f; 数组&#xff1a;(Array)是一种可以按顺序保存数据的数据类型 2.为什么要数组&#xff1f; 思考&#xff1a;如果我想保存一个班里所有同学的姓名怎么办&#xff1f; 场景&#xff1a;如果有多个数据可以用数组保存起来&#xff0c;然后放到一个变量…

【AI视野·今日CV 计算机视觉论文速览 第285期】Mon, 8 Jan 2024

AI视野今日CS.CV 计算机视觉论文速览 Mon, 8 Jan 2024 Totally 66 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Denoising Vision Transformers Authors Jiawei Yang, Katie Z Luo, Jiefeng Li, Kilian Q Weinberger, Yonglong Tian, Yue…

【漏洞复现】Apache Tomcat AJP文件包含漏洞(CVE-2020-1938)

Nx01 产品简介 Apache Tomcat 是一个免费的开源 Web 应用服务器&#xff0c;在中小型企业和个人开发用户中有着广泛的应用。 Nx02 漏洞描述 默认情况下&#xff0c;Apache Tomcat会开启AJP连接器&#xff0c;由于AJP服务&#xff08;8009端口&#xff09;存在文件包含缺陷&…

打造高性价比小程序,轻松降低成本

随着移动互联网的普及&#xff0c;小程序已经成为一个热门的应用开发方向。然而&#xff0c;对于许多企业和个人而言&#xff0c;制作一个小程序的费用却让人望而却步。那么&#xff0c;如何以最低的成本制作一款高性价比的小程序呢&#xff1f; 答案很简单&#xff0c;只需要找…

Spark SQL基础

SparkSQL基本介绍 什么是Spark SQL Spark SQL是Spark多种组件中其中一个,主要是用于处理大规模的结构化数据 什么是结构化数据: 一份数据, 每一行都有固定的列, 每一列的类型都是一致的 我们将这样的数据称为结构化的数据 例如: mysql的表数据 1 张三 20 2 李四 15 3 王五 1…

支付宝异步验签踩的坑

最近公司要做支付宝小程序 我作为服务端就要给小程序配置下单啊&#xff0c;异步回调同步支付状态等功能 就不可避免的使用到了支付宝异步验签 首先背景是我是PHP语言&#xff0c;然后验签方式是RSA2 一开始写原生验签方法&#xff0c;验签失败&#xff0c;后面又搞sdk 验签…

Java进阶十—JDBC

Java进阶十—JDBC 一.说明 用Java语言操作Mysql&#xff0c;首先需要学习Mysql MySQL入门教程-CSDN博客 二.JDBC的由来以及定义 JDBC是什么&#xff1f; Java数据库连接(Java Database Connectivity)简称JDBCJDBC是Java操作各数据库的一种规范&#xff0c;是Java语言中用来…

ChatGPT:人工智能与人类交流的桥梁

在人工智能的浪潮中&#xff0c;ChatGPT以其独特的交流能力成为了一个亮点。作为一个基于强大的GPT-4模型的聊天机器人&#xff0c;ChatGPT不仅仅是技术的展示&#xff0c;它更是人工智能与人类交流的桥梁。 人工智能的语言理解革命 ChatGPT的出现标志着人工智能在语言理解和…

攻防实战-手把手带你打穿内网

六朝何事&#xff0c;只成门户私计&#xff01; 目录 环境配置 网络配置 本次实战绘制出来的网络拓扑图如下&#xff1a; 第一层&#xff1a;12server-web1 信息搜集 网站url&#xff1a; 目录扫描 扫到后台地址&#xff1a; 发现有注册功能&#xff0c; 先注册一下尝试能…

预约上门按摩系统目前面临的挑战有哪些

按摩预约上门服务系统上线之后在运营的过程中主要面临的挑战主要有以下几个方面&#xff1a; 1.技师管理和培训&#xff1a;为了保证服务的质量&#xff0c;需要对技师进行管理和培训。这包括确保技师具备必要的技能和资格&#xff0c;以及提供必要的培训&#xff0c;以确保他们…

[金融支付]EMV是什么?

文章目录 EMVCoEMVCo是谁&#xff1f;EMVCo是做什么的&#xff1f;EMVCo是如何运作的&#xff1f;EMVCo 是否强制要求 EMV 规范&#xff1f; EMVEMV的历史背景EMV技术的一些关键点 EMV TechnologiesEMV 认证EMV的三层认证 EMV规范在全球各地存在差异参考 EMVCo EMVCo是谁&…

系列二、Spring Security中的核心类

一、Spring Security中的核心类 1.1、自动配置类 UserDetailsServiceAutoConfiguration 1.2、密码加密器 1.2.1、概述 Spring Security 提供了多种密码加密方案&#xff0c;官方推荐使用 BCryptPasswordEncoder&#xff0c;BCryptPasswordEncoder 使用 BCrypt 强哈希函数&a…

《BackTrader量化交易图解》第10章:Trade 交易操作

文章目录 10 Trade 交易操作10.1 量化回测分析流程10.2 Cerebro 类模块10.3 案例&#xff1a;Trade 交易10.4 实盘交易机器隐性规则10.5 Stake 交易数额和 Trade 交易执行价格 10 Trade 交易操作 10.1 量化回测分析流程 从本章开始讲解 BackTrader 的实盘操作。前面的章节讲过…

如何监控电脑屏幕-对电脑屏幕进行监控有什么方法?如何实现电脑屏幕监控?

随着电脑的普及&#xff0c;越来越多的人开始需要监控电脑屏幕&#xff0c;无论是出于工作需要还是家庭安全考虑。 然而&#xff0c;如何实现电脑屏幕监控却是一个需要探讨的问题。 一、监控电脑屏幕的方法 使用电脑监控软件&#xff0c;这是一种很常用的监控方式&#xff0c…

vivado编译设置、执行设置、bit流生成设置

合成设置 使用“合成设置”可以指定约束集、合成策略、合成选项&#xff0c;以及要生成的报告。选项由选定的定义综合策略或综合报告策略&#xff0c;但您可以用自己的策略覆盖这些策略设置。您可以选择一个选项来查看对话框底部的描述。了解更多有关“合成设置”的信息&#…