Oracle存储过程~封神之路

news2024/11/15 7:04:55

简介

Oracle 存储过程是 Oracle 数据库中的一种数据处理对象,它可以在数据库中定义一组预定义的 SQL 语句,用于完成特定的数据库操作。存储过程可以被授权的用户调用,并且可以执行多个语句,这些语句可以被视为一个单独的操作,也可以被视为一系列的操作。

使用存储过程可以大大提高数据库的性能和安全性。存储过程可以减少网络流量和请求,同时也可以减少与应用程序之间的接口调用,从而提高了数据库的性能和可靠性。

目录

基本语法, 游标,存储过程。

1、基本语法 

1.1 新建测试窗口

  • New   Test Window 

 

1.2 程序结构

  • 在Java编程中是区分大小写,这里不用区分大小写。
  • DECLARE部分声明变量或游标(结果集类型变量),程序没有变量声明的可以省略或删除。
  • PLSQL可分为三个部分:  变量声明部分,执行部分,异常处理部分。
-- Created on 2023/5/10 by 肖 
declare 
  --声明变量 游标

begin
  -- 执行语句
  
  -- 异常处理
end;

 1.3打印输出

  •  Dbms_Output 为oracle内置程序包,类似Java中的System.out,而put_line() 是调用的方法,相当于println()方法。
  • 需要注意的是:  put_line('hello mr.xiao'); 中  一定是 ' '  号,否则会报错的。
begin
  
  --打印 hello mr.xiao
 Dbms_Output.put_line('hello mr.xiao');
 
end;

 执行结果

  • 如果你不能打印输出,需要开启  set serveroutput on  因为 默认情况下,输出选项是关闭状态。

1.4 变量

变量分两大类如:

  • 普通数据类型(char,varchar2, date, number, boolean, long)
  • 特殊变量类型(引用型变量、记录型变量)

声明变量的方式如:

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

1.4.1 普通变量

变量赋值的方式有两种如:

  • 直接赋值语句     :=      比如:    v_name  := '你才是臭弟弟'
  • 语句赋值,使用select …into … 赋值:(语法 select 值 into 变量)
  -- 打印个人信息,包括: 姓名、薪水、地址
DECLARE
  -- 姓名
  V_NAME VARCHAR2(30) := '你才是臭弟弟'; -- 声明变量直接赋值
  --薪水
  V_SAL NUMBER;
  --地址
  V_ADDR VARCHAR2(200);

BEGIN

  --在程序中直接赋值
  V_SAL := 1800; --工资每月1800 每天笑哈哈

  --语句赋值
  SELECT 'CSDN你才是臭弟弟' INTO V_ADDR FROM DUAL; --不会有人不知道DUAL吧,DUAL 是一个用于描述 Oracle 数据库中的虚拟表的关键字

  --打印变量  注意 || 是拼接
  DBMS_OUTPUT.PUT_LINE('姓名:' || V_NAME || ',薪水:' || V_SAL || ',地址:' ||V_ADDR);

END;

执行结果:

1.4.2 引用型变量

  • 变量的类型和长度取决于表中字段的类型和长度
  • 通过 表名.列名%TYPE 指定变量的类型和长度,例如: v_name  emp.ename%TYPE
  -- 查询emp表中1001号员工的个人信息,打印姓名和薪水
DECLARE
  -- 姓名
  V_NAME EMP.ENAME%TYPE; -- 声明变量直接赋值
  --薪水
  V_SAL  EMP.ESALARY%TYPE;

BEGIN
  --查询表中的姓名和薪水并赋值给变量
  --注意查询的字段和赋值的变量的顺序、个数、类型要一致
  SELECT ENAME, ESALARY INTO V_NAME, V_SAL FROM EMP WHERE EMPLOYEEID = 1001;

  --打印变量
  DBMS_OUTPUT.PUT_LINE('姓名:' || V_NAME || ',薪水:' || V_SAL);

END;

执行结果:

推荐大家使用引用型变量区别:

  •   普通型变量:  V_NAME VARCHAR2(30); 你怎么知道一定VARCHAR2类型,你又怎么知道长度一定是30呢,假设V_NAME VARCHAR2(1);  就对应不上SELECT ENAME, ESALARY INTO V_NAME, V_SAL FROM EMP 这条语句中的 ENAME 的长度了,也就接收不到值了,就会报错。如果要使用普通变量前提是 ,了解查询表中对应字段的 类型 及 长度, 才能基于他们来确定类型长度 这比较繁琐。
  •   引用型变量:  声明一个变量 不再定义类型长度,而是基于接收表字段的类型及长度 来定义。如:V_NAME EMP.ENAME%TYPE;

总结:

 使用普通变量定义方式,需要知道表中列的类型,而使用引用类型,不需要考虑列的类型,使用%TYPE是非常好的编程风格,因为引用型变量更加灵活。

1.4.3 记录型变量

  •  记录型变量 接受表中的一整行记录,相当于Java中的一个对象
  • 语法: 变量名称   表名%ROWTYPE, 例如:v_emp  emp%rowtype;
  -- 查询emp表中1001号员工的个人信息,打印姓名和薪水
DECLARE
  -- 记录型变量接受一行
  V_EMP EMP%ROWTYPE;

BEGIN
  --记录型变量默认接受表中的一行数据,不能指定字段。
  SELECT * INTO V_EMP FROM EMP WHERE EMPLOYEEID = 1001;

  --打印变量,通过变量名.属性的方式获取变量中的值
  DBMS_OUTPUT.PUT_LINE('姓名:' || V_EMP.ENAME || ',薪水:' || V_EMP.ESALARY);

END;

总结:

  • 如果有一张表,有50个字段,那么你程序如果要使用这50字段话,如果你使用引用型变量一个个声明,会特别繁琐,记录型变量可以方便的解决这个问题。

注意错误的使用案例如下:

  • 记录型变量只能存储一个完整的行数据

我把 * 换成 单个字段执行报错,因为上面的变量定义的是一行,而现在只给一个是不行的。

  • 返回的行太多了,记录型变量也接收不了

 现在这条sql 为什么报错,因为现在是全表查询 返回的行数超出了 一个变量只能接收一行,这就和JAVA 类似了,应该用集合去装才可以 ,装进集合在取出来  是不是就跟JAVA 中循环取值差不多。

1.5 流程控制

1.5.1 条件分支

  • IF条件判断~语法

BEGIN

  IF 条件 THEN
      执行语句
  END IF;

END;
  • IF...ELSE 条件判断~语法
BEGIN

 IF 条件 THEN
    执行语句
 ELSE
    执行语句
 END IF;

END;
  • IF...ELSIF...ELSE条件判断~语法,注意关键字:ELSIF。
BEGIN

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

案例:

  --判断emp表中记录是否超过20条,10-20之间,或者10条以下
DECLARE
  --声明变量接受emp表中的记录数
  V_COUNT NUMBER;

BEGIN

  --查询emp表中的记录数赋值给变量

  SELECT COUNT(1) INTO V_COUNT FROM EMP;

  --判断打印

  IF V_COUNT > 20 THEN
    DBMS_OUTPUT.PUT_LINE('EMP表中的记录数超过了20条为:' || V_COUNT || '条。');

  ELSIF V_COUNT >= 10 THEN
    DBMS_OUTPUT.PUT_LINE('EMP表中的记录数在10~20条之间为:' || V_COUNT || '条。');

  ELSE
    DBMS_OUTPUT.PUT_LINE('EMP表中的记录数在10条以下为:' || V_COUNT || '条。');

  END IF;

END;

执行结果:

1.5.2 循环

  • Loop 语法
BEGIN
  LOOP
  	EXIT WHEN 退出循环条件  
  END LOOP;
END;

Loop语法 案例:

  --循环打印 1-5
DECLARE
  --声明循环变量并赋初值
  V_NUM NUMBER := 1;

BEGIN

  LOOP
  
    EXIT WHEN V_NUM > 5;
    
    DBMS_OUTPUT.PUT_LINE(V_NUM);
  
    --循环变量自增
    V_NUM := V_NUM + 1;
  
  END LOOP;

END;

  • While 语法
while(判断循环的条件) loop
	循环的语句;
END loop;

While语法 案例:

DECLARE
    --声明循环变量
    V_NUM NUMBER;
BEGIN
    -- 必须给一个初始值
    V_NUM := 1;
    WHILE(V_NUM < 10) LOOP
        DBMS_OUTPUT.put_line('值为: ' || V_NUM);
        V_NUM := V_NUM + 1;
    END LOOP;
END;

--此循环会先判断再执行语句

  •  FOR循环 语法
FOR 变量名 in 变量的初始值..结束值 lOOP
	循环语句;
END loop;

FOR循环语法 案例:

    --for循环打印 1-10
DECLARE
    --声明循环变量并赋初值
    V_NUM NUMBER ;
BEGIN
	  --此语句会自动将1到10赋值给V_NUM
    FOR V_NUM in 1..10 loop
        DBMS_OUTPUT.put_line('值为: ' || V_NUM);
    END LOOP;
END;

2、游标

2.1 游标说明

  • 用于临时存储一个查询返回的多行数据,通过遍历游标,可以逐行访问处理该结果集的数据。
  • 游标的使用方式:声明→打开→读取→关闭

2.2 语法

游标声明:

CURSOR  游标名[(参数列表)]    IS 查询语句;

游标的打开:

OPEN 游标名;

游标的取值:

FETCH 游标名 INTO 变量列表;

游标的关闭:

CLOSE 游标名;

 注意: 游标名自身是可以带参数的,如果有参数、参数会带入到查询语句中进行查询,游标本质 就是 一个 is 查询语句,也就是说查询结果被放置到游标中。

2.3 游标属性

游标的属性
属性说明
 %FOUND变量最后从游标中获取记录的时候,在结果集中找到了记录。
%NOTFOUND变量最后从游标中获取记录的时候,在结果集中没有找到记录。
%ROWCOUNT当前时刻已经从游标中获取的记录数量。
%ISOPEN 是否打开。
%ROW游标指向的行数。 
%COLUMN游标指向的列数。
%ATTEMPTS尝试获取记录的次数。
%ERROR 发生错误的次数。
%FETCH_STATUS FETCH语句的执行状态,包括成功、失败和出错标志。
%SIZE当前游标指向的记录大小。
%LINE_NUMBER当前行号。
%ERROR_STRING错误信息字符串。
%PROCID当前执行的SQL语句的ID

2.4 无参数游标

  • 使用游标查询emp表中所有员工的姓名和工资,Loop循环依次打印结果集。
--使用游标查询emp表中所有员工的姓名和工资,依次打印结果集。
DECLARE
  --声明游标
  CURSOR C_EMP IS
    SELECT ENAME, ESALARY FROM EMP;

  --声明变量用来接受游标中的元素
  V_ENAME EMP.ENAME%TYPE;

  V_SAL EMP.ESALARY%TYPE;

BEGIN

  --打开游标
  OPEN C_EMP;

  --遍历游标中的值
  LOOP
  
    --通过FETCH语句获取游标中的值并赋值给变量
    FETCH C_EMP
      INTO V_ENAME, V_SAL;
  
    --通过%NOTFOUND判断是否有值,有值打印,没有则退出循环
    EXIT WHEN C_EMP%NOTFOUND;
  
    DBMS_OUTPUT.PUT_LINE('姓名:' || V_ENAME || ',薪水:' || V_SAL);
  
  END LOOP;

  --关闭游标
  CLOSE C_EMP;

END;

执行结果:

2.5 带参数的游标

  • 使用游标查询并打印某部门的员工的姓名和薪资,部门编号为运行时手动输入。
 --使用游标查询并打印某部门的员工的姓名和薪资,部门编号为运行时手动输入。
DECLARE
  --声明游标传递参数
  CURSOR C_EMP(V_EMPLOID EMP.EMPLOYEEID%TYPE) IS
    SELECT ENAME, ESALARY FROM EMP WHERE EMPLOYEEID = V_EMPLOID; 

  --声明变量用来接受游标中的元素
  V_ENAME EMP.ENAME%TYPE;

  V_SAL EMP.ESALARY%TYPE;

BEGIN

  --打开游标并传递参数
  OPEN C_EMP(1001);

  --遍历游标中的值
  LOOP

  --通过FETCH语句获取游标中的值并赋值给变量
    FETCH C_EMP
      INTO V_ENAME, V_SAL;


       --通过%NOTFOUND判断是否有值,有值打印,没有则退出循环
       EXIT WHEN C_EMP%NOTFOUND;
       
       

    DBMS_OUTPUT.PUT_LINE('姓名:' || V_ENAME || ',薪水:' || V_SAL);


  END LOOP;

  --关闭游标
  CLOSE C_EMP;

END;

执行结果:

 注意:%NOTFOUND属性默认值为FLASE,所以在循环中要注意判断条件的位置.如果先判断在FETCH会导致最后一条记录的值被打印两次(多循环一次默认);

错误反例演示:

 反例执行结果:

原因:  %NOTFOUND 默认值是 false,false意味着游标里面默认是有值,到底有值还是没值 需要fetch 好之后才知道有没有值,%NOTFOUND 默认做了一个有值的假设 , 看下面代码:

LOOP


       --通过%NOTFOUND判断是否有值,有值打印,没有则退出循环
       EXIT WHEN C_EMP%NOTFOUND;


     --通过FETCH语句获取游标中的值并赋值给变量
     FETCH C_EMP
        INTO V_ENAME, V_SAL;
       

      DBMS_OUTPUT.PUT_LINE('姓名:' || V_ENAME || ',薪水:' || V_SAL);


END LOOP;

 EXIT WHEN C_EMP%NOTFOUND; 判断有值打印,出去之后 又带着有值的进入到循环中 EXIT WHEN C_EMP%NOTFOUND; 判断没值打印, 所以这次打印的是上次值的。

3、存储过程

3.1 创建存储过程

    持续更新中........................

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

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

相关文章

“深圳首届十大金口碑人物”优必选科技创始人兼CEO周剑获此殊荣

深圳晚报社联合深圳市诚商信用评级有限公司、深圳市诚信营商促进会和中国善网&#xff0c;共同举办了首届“金口碑”评选活动。活动涵盖多个领域&#xff0c;历经多个环节的评定和实地走访&#xff0c;最终有10名个人、20家企业和70家商户成功获得“深圳首届十大金口碑人物”、…

Visual C++实现推箱子游戏的核心算法设计与实现(附源码和和资源)

需要源码和资源请点赞关注收藏后评论区留言私信~~~ 在前面的博客中已经讲解了推箱子游戏的菜单和各种对话框的实现&#xff0c;下面对推箱子游戏的核心算法设计和实现进行讲解 一、地图文件读取模块的设计与实现 地图文件读取模块&#xff0c;主要负责将地图文件进行读取&…

【AI大模型】“讯飞星火”认知大模型正式发布 计划10月底赶超ChatGPT

文章目录 前言你使用过这种对话式AI吗&#xff1f;有什么看法或感受&#xff1f;“讯飞星火大模型将超越chatgpt&#xff1f;”这类型的人工智能对现在的社会有什么意义&#xff1f;这类型的人工智能&#xff0c;未来前景如何&#xff1f;申请体验写在最后 前言 5月6日&#xf…

科普:跨链桥是如何被黑的?

科普&#xff1a;跨链桥是如何被黑的&#xff1f; [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hbvPVTkb-1666679410875)(htTPS://tva1.sinaimg.cn/large/e6c9d24ely1h4r0auxvmxg20tr04ojug.gif)] 跨链桥是一种允许两个独立区块链网络之间进行通信…

【git】用好 stash,工作超nice

一、介绍 如果修改后的内容还不想commit&#xff0c;就可以用git stash命令。它会将工作区和暂存区中的修改(也就是还没commit的内容)都会被保存到堆栈里&#xff0c;并在之后恢复到任意指定的分支上。 二、应用场景 1、在分支a进行开发feature 1时&#xff0c;突然需要紧急…

【AI大模型】讯飞星火大模型能否超越chatgpt?

文章目录 前言你使用过这种对话式AI吗&#xff1f;有什么看法或感受&#xff1f;“讯飞星火大模型将超越chatgpt&#xff1f;”这类型的人工智能对现在的社会有什么意义&#xff1f;这类型的人工智能&#xff0c;未来前景如何&#xff1f;申请体验写在最后 前言 5月6日&#xf…

机器学习-10 聚类算法

聚类算法 算法概括聚类&#xff08;clustering&#xff09;聚类的概念聚类的要求聚类与分类的区别 常见算法分类聚类算法中存在的问题 距离度量闵可夫斯基距离欧式距离&#xff08;欧几里得距离&#xff09;曼哈顿距离切比雪夫距离皮尔逊相关系数余弦相似度杰卡德相似系数 划分…

建造者模式详解:建造随意搭配的肯德基套餐

一、简介 建造者模式&#xff08;Builder Pattern&#xff09;是五种创建型设计模式之一&#xff0c;它将一个复杂对象的构建与其表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。这句话怎么理解呢&#xff1a;一个对象的构建过程本质上就是这个对象包含的所有成员…

一觉醒来IDEA感觉不香了,AI智能编程工具Cursor使用

一、简介 为使用人工智能编程而构建的编辑器&#xff0c;一款人工智能编程软件、智能Ai代码生成工具。 它有什么特点呢&#xff1f; 集成了GPT-4&#xff0c;国内可用&#xff0c;不仅有ChatGPT的聊天功能&#xff0c;还有强大的自动代码生成能力&#xff0c;简直是编码神器。 …

Java中常见的几种数组排序方法

这篇文章总结一下我学习到的几种常见的数组排序方法 冒泡排序 冒泡排序在我看来是最简单、最基本的排序方法&#xff0c;我们应当将冒泡排序的原理和代码熟记于心。 冒泡排序的原理十分简单&#xff1a;用数组的第一个元素和第二个元素进行比较&#xff0c;将大的放到后面&a…

【Java编程系列】Minio实现文件上传下载

热门系列&#xff1a; 【Java编程系列】Amazon S3实现文件上传下载 目录 热门系列&#xff1a; 1、前言 2、Minio实战代码 2.1 Minio环境部署 2.2 Minio的Sdk对接实现 2.2.1 Minio Maven依赖 2.2.2 minio配置与初始化 2.2.3 上传文件 2.2.4 下载文件 2.2.5 生成文件…

【LLM大模型】LLM模型和指令微调方法

note 文章目录 note零、AIGC生成式模型1. 核心要素2. LLM evolutionary tree3. 几个bigScience里的概念 二、LLM大模型1. ChatGLM&#xff08;1&#xff09;GLM-130B&#xff08;2&#xff09;ChatGLM-6B 2. LLaMA3. RoBERTa4. Bloom5. PaLM 三、模型指令微调1. 指令微调的注意…

使用Vue+Vue-router+el-menu实现菜单功能实战

前言 上节回顾 上一小节我们使用H5+CSS3实现了管理平台的架构布局,并且通过Vuex的使用,获取到前端数据本地化存储的username,绑定到右上角进行全局展示。还不了解上下文的同学可以回顾一下 使用Vue+Vuex+CSS3完成管理端响应式架构模板实战 。 本节介绍 本小节已经是专栏的…

【C语言】字符串---刷题篇

1.统计字符串中元音字母的字数 2.使用起泡法和选择法将字符串按ASCII码值从小到大排列 3.将字符串中的数字字符倒置&#xff0c;即‘0’变‘9’、‘1’变‘8’、…、‘9’变‘0’.例如&#xff1a;字符串“a1b2c3d4e9f0”倒置变为“a8b7c6d5e0f9 4.将一个字符串中从第m个字符开…

187页9万字企业大数据治理与云平台实施方案(word)

1 项目背景概述 1.1 项目背景理解 1.2 项目需求范围 2 项目技术方案 2.1 咨询研究服务方案 2.1.1 咨询研究服务内容 2.1.2 咨询服务方案 2.2 第三方独立评估 2.2.1 概述 2.2.2 管理办法 2.2.3 考核机制 2.3 安全咨询研究服务方案 2.3.1 安全咨询服务内…

大唐杯学习笔记(1)—— 5G网络架构与组网部署

目录 一、名词汇总1.核心网与接入网2.5G网络架构3.核心网架构演进(1)2G核心网(1)3G&#xff0c;4G核心网 4.4G核心网架构5.5G核心网架构6.5G接入网网架构7.主要网元功能 二、5G主要网元功能1.用户面功能UPF(User Plane Function)2.会话管理功能SMF(Session Management Function…

【SpringCloud微服务实践】服务注册与发现(理论)

注册与发现 在之前的示例中&#xff0c;采取的是硬编码的方式&#xff0c;需要调用的微服务的地址是被我们写死在文件或代码中的。在传统应用程序中&#xff0c;一般都是这么做的&#xff0c;然而这种方式存在不少缺陷&#xff1a; 静态配置&#xff1a;因为是写死的网络地址…

Cy5.5-PEG2000-Biotin,Cy5.5-聚乙二醇-生物素;Biotin-PEG-Cy5.5;可用于检测抗生物素、链霉亲和素或中性生物素

Cyanine5.5-PEG-Biotin&#xff0c;Cy5.5-聚乙二醇-生物素 中文名称;Cy5.5-聚乙二醇-生物素 英文名称;Cyanine5.5-PEG-Biotin 性状&#xff1a;粘稠液体或固体粉末&#xff0c;取决于分子量大小 溶剂&#xff1a;溶于水、氯仿、DMSO等常规性有机溶剂 分子量PEG:1k、2k、3.…

【Python】JupyterLab报错:Server Connection Error如何解决?

文章目录 一、报错情形二、深层原因三、解决方案3.1 重命名用户名3.2 启用Administrator账户3.3 切换Administrator账户3.4 重命名用户文件夹3.5 修改注册表3.6 修改环境变量 小结 Anaconda的JupyterLab 作为优秀的网页编辑器&#xff0c;非常适用于编写Python程序&#xff0c;…

Qt的窗口的设置

窗口外部设置 Qt::WindowFlags Qt::WidgetQWidget默认窗口&#xff0c;没有父窗口的话&#xff0c;是一个独立窗口Qt::Window是一个窗口&#xff0c;有窗口边框和标题Qt::Dialog是一个对话框窗口Qt::Sheet是一个窗口或部件Macintosh表单(sheet)Qt::Drawer是一个窗口或部件Ma…