PlSql存储过程基础

news2024/11/28 14:43:11

目录儿

  • 常用指令
  • 1. 什么是PLSQL语言
  • 2. PLSQL程序结构
    • 2.1 第一个程序 HelloWord:
    • 2.2 执行程序
      • 2.2.1 在工具中执行
      • 2.2.2 在sqlplus客户端中执行(命令行)
  • 3. 变量
    • 3.1 普通变量
    • 3.2 引用型变量
    • 3.3 记录型变量
  • 4. 流程控制
    • 4.1 条件分支
    • 4.2 循环
  • 5. 游标
    • 5.1 定义
    • 5.2 语法
    • 5.3 游标的属性
    • 5.4 创建和使用
    • 5.5 带参游标
  • 6. 存储过程⭐
    • 6.1 概念
    • 6.2 语法
    • 6.3 无参存储
    • 6.4 带输入参数的存储过程
    • 6.5 带输出参数的存储过程
    • 6.6 异常处理

Oracle数据库封装了 PLSQL语言。

常用指令

# cmd打开 sqlplus 客户端
sqlplus /nolog
# 以 DBA 角色连接
conn /as sysdba;

1. 什么是PLSQL语言

PLSQL全称Procedure Language SQL,是OracleSQL的一种过程化拓展,在SQL命令语言中增加了过程处理语句(如分支,循环等),是SQL语言具有过程处理的能力。

把复杂的业务逻辑放到数据库中处理,能够减少数据库和服务之间的网络交互,提高执行效率。

PLSQL是一种不区分大小写的语言(大小写不敏感)

2. PLSQL程序结构

一个程序分为三个部分:

DECLARE
	--声明(变量,游标)
BEGIN
	-- 执行体(业务逻辑)
	-- [异常处理]
END;

其中DECLARE部分在不用声明变量、游标的情况下可以省略。

2.1 第一个程序 HelloWord:

DECLARE
	--Local variables here
	I INTEGER:
BEGIN
	--在`DBMS Output`窗口打印 "hello world"
	DBMS_OUTPUT.PUT_LINE ('hello world'); 
END;

DBMS_OUTPUTOracle内置的程序包,.PUT_LINE()是包内函数

2.2 执行程序

2.2.1 在工具中执行

在工具中,直接点击编辑窗口的执行按钮即可。

2.2.2 在sqlplus客户端中执行(命令行)

在命令行中,执行程序需要在程序最后输入/表示程序结束,这样回车才会执行程序,否则会认为程序还没结束而换行。

连接到:
Oracle Database 10g Express Edition Release 10.2.0.1.0-Production

SQL> begin
  2   DBMS_OUTPUT.PUT_LINE('HELLO WORLD');
  3  END;
  4  /
HELLO WORLD
PL/SQL过程已成功完成。

默认情况下,sqlplus客户端默认关闭打印输出,因此没有显示打印结果,可以通过命令set serveroutput on开启:

SQL> set serveroutput on
SQL> begin
  2   DBMS_OUTPUT.PUT_LINE('HELLO WORLD');
  3  END;
  4  /
HELLO WORLD

PL/SQL 过程已成功完成。

3. 变量

  1. 普通数据类型:char、varchar2、date、number、boolean、long
  2. 特殊变量类型:引用型变量、记录型变量

变量声明格式

  • 变量名 变量类型(变量长度) 例如:v_name varchar2(20);

变量赋值格式

  • 直接赋值:v_name := 'zhangsan'
  • 语句赋值:select 值 into 变量

3.1 普通变量

【示例】打印人员个人信甚,包括:姓名、薪水、地址

DECLARE
    -- 姓名
    v_name VARCHAR2(20) := 'Haydon';
    -- 薪水
    v_sal NUMBER;
    -- 地址
    v_addr VARCHAR2(200);
BEGIN
    --直接赋值
    v_sal := 8888;
    --语句赋俏
    SELECT 'xxx' INTO v_addr FROM DUAL;
    --打印输出
    DBMS_OUTPUT.PUT_LINE('姓名:'|| v_name ||'薪水:'|| v_sal ||'地址:' || v_addr);
END;

执行结果:
在这里插入图片描述

3.2 引用型变量

变量的类型和长度取决于表中字段的类型和长度
通过表名.列名%TYPE指定变量的类型和长度,例如:v_name emp.ename%TYPE;

【示例】查询emp表中7839号员工的个人信息,打印姓名和薪水

DECLARE
    v_name emp.ename&TYPE;
    v_sal emp.sal&TYPE;
BEGIN
   SELECT ENAME,SAL INTO v_name,v_sal FROM EMP WHERE EMPNO = 7839;
    --打印输出
    DBMS_OUTPUT.PUT_LINE('姓名:'|| v_name ||'薪水:'|| v_sal ||'地址:' || v_addr);
END;

引用型变量的好处:
使用普通变量定义方式,需要知道表中列的类型,而使用弱引用类型,不需要考虑列的类型,使用%TYPE是非常好的编程风格,因为它使得PL/SQL更加灵活,更加适应于对数据库定义的更新。

3.3 记录型变量

接受表中的一整行记录,相当于Java中的一个对象
语法:变量名称 表名%ROWTYPE,例如:v_emp emp%ROWTYPE;

【示例】查询并特打印7839号员工的姓名和薪水

DECLARE
	-- 记录型变量
    v_emp emp%ROWTYPE;
BEGIN
   SELECT * INTO v_name,v_sal FROM EMP WHERE EMPNO = 7839;
    --打印输出
    DBMS_OUTPUT.PUT_LINE('姓名:'|| v_emp.ename ||'薪水:'|| v_emp.sal ||'地址:' || v_emp.addr);
END;
  1. 如果有一个表,有100个字段,那么你程序如果要使用这100字段话,如果你使用弱引用型变量一个个声明,会特别麻烦,记录型变量可以方便的解决这个问题
  2. 因为记录型变量是存储一行数据的变量,因此不能指定查询字段,要用*,否则报错
  3. 因为记录型变量是存储一行数据的变量,因为查询的结果不能>1,否则报错

4. 流程控制

4.1 条件分支

BEGIN
	IF 条件1 THEN 执行1
	ELSIF 条件2 THEN 执行2
	ELSE 执行3
	END IF;
END;

注意ELSIF是少一个e的。

【示例】
在这里插入图片描述

4.2 循环

loop循环:
【示例】打印1~10

DECLARE
	--声明循环变量
	V_NUM NUMBER :1;
BEGIN
	LOOP
		EXIT WHEN V_NUM > 10;
		DBMS_OUTPUT.PUT_LINE (V_NUM);
		--循环变量的自增
		V_NUM := V_NUM + 1;
	END LOOP;
END:

5. 游标

5.1 定义

用于临时存储一个查询返回的多行数据(结果集,类似于Java的Jdbc连接返回的ResultSet集合),通过遍历游标,可以逐行访问处理该结果集的数据。
游标的使用方式:声明 一> 打开 一> 读取 一> 关闭

5.2 语法

声明游标:CURSOR 游标名[(参数列表)] IS 查询语句;
开启游标:OPEN 游标名;
游标取值:FETCH 游标名 NTO 变量列表;
关闭游标:CLOSE 游标名;

5.3 游标的属性

属性返回值类型说明
%ROWCOUNT整形获得 FETCH 语句返回的数据行数
%FOUND布尔型最近的 FETCH 语句能拿到数据则为真,否则为假
%NOTFOUND布尔型%FOUND 属性返回值相反
%ISOPEN布尔型游标已经打开时值为真,否则为假

其中%NOTFOUND是在游标中找不到元素的时候返回TRUE,通常用来判断退出循环,他的默认值是false,因此用%NOTFOUND作判断之前,应该先执行 FETCH 语句使%NOTFOUND带上真实的值。

5.4 创建和使用

【示例】使用游标查询 emp 表中所有员工的姓名和工资,并将其依次打印出来。

-- 使用游标查诡m表中所有员工的名和工资,并将其依次打印出来。
DECLARE
	-- 声明游标
	CURSOR c_emp IS SELECT ename,sal FROM emp;
	-- 声明变量接受游标中的数据
	v_ename emp.enames%TYPE;
	v_sal emp.sal%TYPE;
BEGIN
	-- 打开游标
	OPEN c_emp;
	-- 遍历游标
	LOOP
		--获取游标中的数据
		FETCH c_emp INTO v_ename,v_sal;
		--退出循环条件
		EXIT WHEN c_emp%NOTFOUND;
		DBMS_OUTPUT.PUT_LINE(v_ename || '-' || v_sal);
	END LOOP;
	--关闭游标
	CLOSE c_emp;
END;

5.5 带参游标

【示例】使用游标查询并打印某部门的员工的姓和薪资,部门编号为运行时手动输入

-- 使用游标查诡m表中所有员工的名和工资,并将其依次打印出来。
DECLARE
	-- 声明含参游标
	CURSOR c_emp(v_deptno emp.deptno$TYPE) IS SELECT ename,sal FROM emp WHERE deptno = v_deptno;
	-- 声明变量接受游标中的数据
	v_ename emp.enames%TYPE;
	v_sal emp.sal%TYPE;
BEGIN
	-- 打开游标,同时传入参数
	OPEN c_emp(10);
	-- 遍历游标
	LOOP
		--获取游标中的数据
		FETCH c_emp INTO v_ename,v_sal;
		--退出循环条件
		EXIT WHEN c_emp%NOTFOUND;
		DBMS_OUTPUT.PUT_LINE(v_ename || '-' || v_sal);
	END LOOP;
	--关闭游标
	CLOSE c_emp;
END;

6. 存储过程⭐

6.1 概念

之前我们编写的PLSQL程序可以进行表的操作,判断,循环逻辑处理的工作,但无法重复调用。

可以理解之前的代码全都编写在了main方法中,是匿名程序。JAVA可以通过封装对像和方法来解决程序的复用问题。

PLSQL是将一个个PLSQL的业务处理过程存储起来进行复用,这些被存储起来的PLSQL程序称之为 存储过程

存储过程作用:

  1. 在开发程序中,为了一个特定的业务功能,会向数据库进行多次连接关闭连接和关闭是很耗费资源),需要对数据库进行多次I/O读写,性能比较低。如果把这些业务放到PLSQL中,在应用程序中只需要调用PLSQL就可以做到连接关闭一次数据库就可以实现我们的业务,可以大大提高效率。
  2. ORACLE官方给的建议:能够让数据库操作的不要放在程序中 。在数据库中实现基本上不会出现错误,在程序中操作可能会存在错误.(如果在数据库中操作数据,可以有一定的日志恢复等功能.)

很奇怪,因为之前没有用过Oracle数据库,通常都是使用Mysql配合Mybatis/Mybatis puls做持久层操作,连接数据库就是做一些比较基础的增删改查,遍历封装什么的存储过程都放到应用程序的service里面做,说是减少数据库的负担云云。
·
Oracle官方却提倡把存储过程复杂业务放到数据库中做,减少连接次数,提升效率,保障安全。
·
在使用Oracle的时候,Oracle是推荐尽可能将所有的操作都放在Plsql中的,但是在使用Mysql的时候是不让使用存储过程的,为什么?
·
下面这个回答感觉是这种分歧的主因:
·
因为Mysql中,存储过程不是一次编译的,而是对每个会话在执行的时候编译一次,在会话结束的时候抛弃,而且在执行alter/procedure的时候是会将所有会话对这个存储过程持有的存储过程的版本抛弃掉。同时没有包的概念,没有类库,没有面向对象的概念,所以相对Oracle来说,Mysql额存储过程不是很好的选择

6.2 语法

CREATE OR REPLACE PROCEDURE 过程名称[(参数列表)] IS
BEGIN
	-- 业务
END [过程名称];

根据参数的类型,我们将其分为3类:

  • 不带参数的
  • 带输入参数的
  • 带输入输出参数(返回值)的

6.3 无参存储

创建存储过程(这里用的Oracle Sql Developer)

在过程文件夹右键 → 新建过程
在这里插入图片描述
选择方案,输入名称
在这里插入图片描述
编辑过程代码

CREATE OR REPLACE PROCEDURE PRO_HELLO IS 
	--声明变量
BEGIN
	dbms_output.put_line ('hello world');
END PRO_HELLO;

注意
第一个问题:isas是可以互用的,用哪个都没关系
第二个问题:过程中可以不用declare关键字

保存即可
在这里插入图片描述
直接测试:
在这里插入图片描述
如果是在sqlplus上用 exec 指令调用:

C:\Users\82009816.GZCASCADE>sqlplus

SQL*Plus: Release 19.0.0.0.0 - Production on 星期三 510 10:48:34 2023
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle.  All rights reserved.

请输入用户名:  DMG
输入口令:
上次成功登录时间: 星期三 510 2023 10:48:16 +08:00

连接到:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0

SQL> set serveroutput on;
SQL> exec pro_hello
hello world

PL/SQL 过程已成功完成。

6.4 带输入参数的存储过程

【示例】查询并用打印某个员工(如7839号员工)的姓名和薪水。要求,调用的时候传入员工编号,自动控制台打印,

CREATE OR REPLACE PROCEDURE P_QUERYNAMEANDSAL(I_EMPNO IN EMP.EMPNO%TYPE) IS
	--声明变量接授查询结果
	V_ENAME EMP.ENAME%TYPE;
	V_SAL   EMP.SAL%TYPE;
BEGIN
	--根据用户传递的员工号查询姓名和蕲水
	SELECT ENAME,SAL INTO V_ENAME,V_SAL FROM EMP WHERE EMPNO = I_EMPNO;
	--打印结果
	DBMS_OUTPUT.PUT_LINE('姓名:' || V_ENAME || ',薪水:'|| V_SAL);
END P_QUERYNAMEANDSAL;

参数包括 IN OUT INOUT三种,对应单纯输入单纯输出输入输出作用。

6.5 带输出参数的存储过程

【示例】输入员工号查询某个员工(7839号员工)信息,要求,将薪水作为返回值输出,给调用的程序使用

--输入员工号查询某个员工(7839号员工)信息,要求,将薪水作为返回值输出,给调用的程序使用
CREATE OR REPLACE PROCEDURE P_QUERYSAL_OUT(
			I_EMPNO IN EMP.EMPNO%TYPE,
			O_SAL OUT EMP.SAL%TYPE) IS
BEGIN
	SELECT SAL INTO O_SAL FROM EMP WHERE EMPNO = I_EMPNO;
END P_QUERYSAL_OUT;

PLSQL工具调用:

--Created on 2018/3/22 by ADMINISTRATOR
declare
--明变量接受存储过军中的榆出参数
	v_sal emp.sal&TYPE;
BEGIN
	p_querysal_out(7839,v_sal)
	dbms_output.put_line(v_sal)END;

6.6 异常处理

在一个procedure中,通常都包含着异常处理部分

我们可以声明自己的异常,并在处理过程中手动抛出,然后在异常捕捉中做相应的处理。

【示例】

    PROCEDURE pro_myprocedure_test (v_status OUT VARCHAR2) AS
    	-- 声明自定义异常
        MYEXCEPTION_ONE EXCEPTION; 
        MYEXCEPTION_TWO EXCEPTION;	
        MYEXCEPTION_THREE EXCEPTION;	
    BEGIN
        IF 条件1
        THEN RAISE EXC_REQUIRED_PARAM_EMPTY; -- 抛出自定义异常
        END IF;
        IF 条件2 THEN RAISE EXC_DELIVERY_COMPLETED;   -- 抛出自定义异常
        ELSIF 条件3 THEN RAISE EXC_DELIVERY_CANCELED; -- 抛出自定义异常
        END IF;
        v_status := 0;
    -- 异常捕捉处理
    EXCEPTION
        WHEN MYEXCEPTION_ONE THEN   -- 处理 MYEXCEPTION_ONE 异常
            ROLLBACK;
            v_status := 1;
        WHEN MYEXCEPTION_TWO THEN   -- 处理 MYEXCEPTION_TWO 异常
            ROLLBACK;
            v_status := 2;
        WHEN MYEXCEPTION_THREE THEN	-- 处理 MYEXCEPTION_THREE 异常
            ROLLBACK;
            v_status := 3;
        WHEN OTHERS THEN        	-- 其他异常
            ROLLBACK;
            v_status := 4;
    END pro_myprocedure_test;

参考资料:
哔哩哔哩 丫丫5358 基于oracle数据库的PLSQL编程以及存储过程的创建和使用视频
https://www.bilibili.com/video/BV1Bb411E74d/?p=3&share_source=copy_web&vd_source=e22a75a6781804ee25ce46a2afc235ce

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

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

相关文章

或许你需要这套uni-app打包android与ios流程

1、hbuilder每个账户的每日云打包有上限次数限制,超出次数要么换账户要么换成本地打包(uni-app提供了足够多云端的打包次数) 2、android打包,也就是apk包 优先搞明白两个需求: 、android包名是否为默认值,如果是默认值&#xf…

基于轻量化深度学习网络的工业环境小目标缺陷检测

源自:控制与决策 作者:叶卓勋 刘妹琴 张森林 摘 要 工业环境下表面缺陷检测是质量管理的重要一环, 具有重要的研究价值.通用检测网络(如YOLOv4)已被证实在多种数据集检测方面是有效的, 但是在工业环境的缺陷检测仍需要解决两个问题: 一是缺陷实例在…

【接口测试】

【接口测试】 1、分层测试理论: UI测试(测试成本最高,发现BUG时间最晚) 接口测试 单元测试 2、协议分析工具 1)网络监听 TcpDump Wireshark 2)协议客户端工具 curl、postman 3)代理Pr…

phpstorm+phpstusy配置xdebug

真心觉得配置好麻烦呀 phpstorm版本: php版本用的7.3.4nts phpstudy版本:8.1.3 先下载xdebug,我用的是php_xdebug-3.1.6-7.3-vc15-nts-x86_64,phpstudy自带的那个xdebug我配置完不起作用 把下完的xdebug放到php下etc目录里,并改名为php_x…

C语言小项目之三子棋

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C语言学习分享⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习更多C语言知识   🔝🔝 三子棋 1. 前言📕2. 思…

【英】考虑多能负荷不确定性的区域综合能源系统鲁棒规划(MatlabPython代码)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

寅家科技完成近亿元B1轮融资,加速高阶智能驾驶布局

近日,寅家科技宣布完成近亿元人民币B1轮融资,本轮融资由东方富海、深创投、深圳高新投联合投资,所募资金主要用于公司高阶智能驾驶技术产品的研发迭代,以及智能驾驶产品量产、海外市场开拓,从而进一步提升核心产品的市…

Solow模型推导模拟

Solow模型推导模拟 文章目录 Solow模型推导模拟[toc]1 Solow模型推导2 Solow模型模拟 1 Solow模型推导 在存在资本折旧、技术进步和人口增长条件下,有效劳动人均资本为 k ˙ ( t ) K ˙ ( t ) A ( t ) L ( t ) − K ( t ) [ A ( t ) L ( t ) ] 2 [ A ( t ) L ˙ …

腾讯云网站备案流程步骤、备案审核通过时间详细说明

腾讯云网站备案流程先填写基础信息、主体信息和网站信息,然后提交备案后等待腾讯云初审,初审通过后进行短信核验,最后等待各省管局审核,前面腾讯云初审时间1到2天左右,最长时间是等待管局审核时间,网站备案…

css新手引导实现方式总结

新手引导功能一般都是用一个半透明的黑色进行遮罩,蒙层上方对界面进行高亮,旁边配以弹窗进行讲解,样式如下 但是由于交互不同,实现方案也不一样,下面就针对不用的交互,总结了不同的实现方法(下文…

路由和寻址的区别

如果说传输层协议,除了 TCP/UDP,我们还可以有其他选择,比如 Google 开发的 QUIC 协议,帮助在传输层支持 HTTP 3.0 传输。但是在网络层,IP 协议几乎一统天下。IP 协议目前主要有两个版本 IPv4 和 IPv6。 根据 Google 统…

开发者一定要知道的 API 管理五大趋势

API First 大势所趋,APIaaS(API 作为服务)也将受到越来越多企业和组织的选择,研发团队对 API 研发管理工具的要求也水涨船高。 API 在今天的数字化世界中扮演着至关重要的角色,随着云计算、物联网、微服务尤其是 AI 等…

Uniapp 引入uView-ui 插件

前言 最近在写uniapp,用了一下原生的ui框架感觉不是很好看,打算去插件市场上面找一下好看的UI插件。学习不是闭门造车,自己重复造轮子。能自己解决和会不会用别人的方法是两回事。我自己也能写UI界面逻辑,但是这样太费时间了。最…

线宽变大,损耗变小;线宽无限大,损耗无限小?

一博高速先生成员:黄刚 作为高速信号传输的重要的指标之一,损耗,无论是对硬件工程师,设计工程师还是我们SI工程师来说,都会是非常的关注。而对于像背板传输这种长距离的走线系统或是像芯片测试板要求损耗极小的情况&a…

港联证券|港交所内地路演人气爆棚 新一轮上市改革加速推进

5月10日,香港交易所在深圳举行未来科技峰会,拉开了港股特专科技上市新规内地路演推广的序幕。 今年3月底,港交所正式推出特专科技公司上市新规,《主板上市规则》新增18C章,并于3月31日起接收特专科技公司上市申请&…

JavaWeb《后端内容:2. MVC-ServletContext-IOC-事务管理-过滤器Filter》

目录 1. 准备和回顾 2. MVC-reflect 3. MVC-dispatcherServlet 3.1 思路部分 3.2 Debug部分 3.3 基于controller进行优化 4. Servlet-api 4.1 回顾 4.2 Init方法 1. 获取ServletConfig config getServletConfig(); 2. 获取初始化参数值:config.getInitP…

静态库(lib),动态库(dll)

我之前有一篇文章讲过静态链接库和动态链接库,大家可以点击链接去看一下:静态链接库,动态链接库【滴水逆向三期48笔记】,由于不是系统学习Windows编程,感觉那时候就是囫囵吞枣,今天又学习了一遍&#xff0c…

基于Keil生成外部Nor Flash下载算法,并使用J-Flash直接烧录(以W25Q64为例)

需要的软件: Keil STM32CubeMX J-Flash 参考文档: 方法1:在Keil中点击Help→uVision Help,然后再搜索框中输入FLM,点击列出主题,可以看到生成下载算法的大致步骤: 方法2:在ARM Ke…

带你玩转三子棋—【C语言】

目录 前言: 1. 菜单的打印 2. game函数的实现 2.1 初始化棋盘 2.2 显示棋盘 2.3 玩家下棋 2.4 电脑下棋 2.5 判断输赢 2.6 判断棋盘是否满了 3. 全部代码 3.1 game.h 3.2 game.c 3.3 test.c 前言: 为了实现三子棋,首先我们应该…

frp将配置写在代码中重新打包

frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。在有些情况下我们需要隐藏配置信息,尤其是客户端(比如我们要在第三方电脑…