oracle存储过程入门详解 oracle存储过程语法

教学大纲:PLSQL编程:Hello World、程序结构、变量、流程控制、游标.存储过程:概念、无参存储、有参存储(输入、输出).J***A调用存储存储过程.1。PLSQL编程1.1。概念和目的什么是PL/SQL?PL/SQL(Procedure Language/SQL)PLSQL是Oracle对sql语言的过程化扩展 (类似于Basic...

教学大纲:

PLSQL编程:Hello World、程序结构、变量、流程控制、游标.存储过程:概念、无参存储、有参存储(输入、输出).J***A调用存储存储过程.

1。PLSQL编程

1.1。概念和目的

什么是PL/SQL?

PL/SQL(Procedure Language/SQL)PLSQL是Oracle对sql语言的过程化扩展 (类似于Basic)指在SQL命令语言中增加了过程处理语句(如分支、循环等),使SQL语言具有过程处理能力。

1.2。程序结构

通过Plsql Developer工具的测试窗口创建一个程序模板,或者通过语句在sql窗口中编写。

提示:PLSQL语言不区分大小写。

PL/SQL可以分为三个部分:声明部分、可执行部分和异常处理部分。

-- Created on 2018/3/21 by ADMINISTRATOR DECLARE -- 声明变量、游标。 I INTEGER;BEGIN -- 执行语句 --[异常处理]?END;

声明部分用于声明变量或游标(结果集类型变量),如果程序中没有变量声明,可以省略。

1.3。你好世界

BEGIN? --打印hello world? DBMS_OUTPUT.PUT_LINE('hello world');?END;

其中DBMS_OUTPUT是oracle内置包,相当于Java中的System.out,PUT_LINE()是被调用的方法,相当于println()方法。

您还可以在sqlplus中编写和运行PLSQL程序:

SQL> BEGIN 2 3 --打印hello world 4 5 DBMS_OUTPUT.PUT_LINE('hello world'); 6 7 END; 8 /PL/SQL 过程已成功完成。

执行后,不显示输出结果。默认情况下,输出选项是关闭的。我们需要打开set serveroutput on

在SQLPLUS中执行PLSQL程序需要在程序末尾加一个/来标记程序的结束。

1.4。变量

PLSQL编程中的常见变量分为两类:

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

该变量声明如下

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

1.4.1。公共变量

有两种方法可以给变量赋值:

直接赋值语句 := 比如: v_name := ‘zhangsan’语句赋值,使用select …into … 赋值:(语法 select 值 into 变量)

[示例]打印员工的个人信息,包括姓名、工资和地址。

-- 打印人员个人信息,包括: 姓名、薪水、地址DECLARE -- 姓名 V_NAME VARCHAR2(20) := '张三'; -- 声明变量直接赋值 --薪水 V_SAL NUMBER; --地址 V_ADDR VARCHAR2(200);?BEGIN? --在程序中直接赋值 V_SAL := 1580;? --语句赋值 SELECT '上海市传智播客' INTO V_ADDR FROM DUAL;? --打印变量 DBMS_OUTPUT.PUT_LINE('姓名:' || V_NAME || ',薪水:' || V_SAL || ',地址:' ||V_ADDR);?END;

1.4.2。引用变量

变量的类型和长度取决于表中字段的类型和长度。

通过表名指定变量的类型和长度。列名%TYPE,例如:v _ name emp.ename % TYPE

[示例]查询emp表中编号为7839的员工的个人信息,打印姓名和工资。

-- 查询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);?END;

参考变量的好处:

使用通用变量定义方法,需要知道表中列的类型,而使用引用类型,不需要考虑列的类型。使用%TYPE是一种非常好的编程风格,因为它使PL/SQL更灵活,更适合更新数据库定义。

1.4.3。记录变量

接受一个表中的一整行记录,相当于Java中的一个对象。

语法:变量名表名%ROWTYPE,例如:v _ EMP EMP % ROWTYPE;

[示例]

并打印7839号员工的姓名和工资。

-- 查询emp表中7839号员工的个人信息,打印姓名和薪水DECLARE -- 记录型变量接受一行 V_EMP EMP%ROWTYPE;?BEGIN --记录型变量默认接受表中的一行数据,不能指定字段。 SELECT * INTO V_EMP FROM EMP WHERE EMPNO = 7839;? --打印变量,通过变量名.属性的方式获取变量中的值 DBMS_OUTPUT.PUT_LINE('姓名:' || V_EMP.ENAME || ',薪水:' || V_EMP.SAL);?END;

如果有一个表有100个字段,如果你的程序要使用这100个字段,如果你用引用变量一个一个的声明,会特别麻烦。记录变量可以方便地解决这个问题。

错误使用:

1.记录变量只能存储完整的一行数据。

2.返回的行数太多,记录变量无法接收。

1.5。过程控制

1.5.1。条件分支

语法:

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

关键词:ELSIF

[示例]确定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。循环

ORACLE中有三种循环模式,这里不展开,只介绍其中一种:loop循环。

语法:

BEGIN LOOP EXIT WHEN 退出循环条件 END LOOP;END;

[示例]打印数字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;

2。游标

2.1。什么是光标

用于临时存储查询返回的多行数据(ResultSet,类似于Java Jdbc连接返回的结果集)。通过遍历光标,可以逐行访问处理结果集的数据。

游标的用法:declare & # 8212& gt打开—& gt阅读—& gt关闭

2.2。语法

光标声明:

CURSOR cursor name [(参数列表)]是一个查询语句;

光标打开:

打开光标名称;

光标的值:

将光标名称提取到变量列表中;

光标关闭:

关闭光标名称;

2.3。游标的属性

游标属性的返回值类型的说明。

如果在游标中找不到任何元素,则%NOTFOUND返回TRUE,这通常用于确定退出循环。

2.4。创建和使用

[示例]用光标查询emp表中所有员工的姓名和工资,并依次打印出来。

--使用游标查询emp表中所有员工的姓名和工资,并将其依次打印出来。DECLARE --声明游标 CURSOR C_EMP IS SELECT ENAME, SAL FROM EMP;? --声明变量用来接受游标中的元素 V_ENAME EMP.ENAME%TYPE;? V_SAL EMP.SAL%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_EMPNO EMP.EMPNO%TYPE) IS SELECT ENAME, SAL FROM EMP WHERE EMPNO = V_EMPNO;? --声明变量用来接受游标中的元素 V_ENAME EMP.ENAME%TYPE;? V_SAL EMP.SAL%TYPE;?BEGIN? --打开游标并传递参数 OPEN C_EMP(10);? --遍历游标中的值 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;? --关闭游标 CLOSE C_EMP;?END;

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

3。存储过程

3.1。概念函数

我们之前写过的PLSQL程序,可以进行表运算,判断,循环逻辑处理,但是不能重复调用。

可以理解为前面的代码都是用***in方法写的,是匿名程序。J***A可以通过封装对象和方法来解决重用问题。

PLSQL是为了存储PLSQL的业务流程以供重用。这些存储的PLSQL程序称为存储过程。

存储过程的功能:

1.在开发过程中,对于一个具体的业务功能,会多次连接和关闭数据库(连接和关闭都是非常消耗资源的),需要多次读写数据库,所以性能比较低。如果把这些服务放到PLSQL中,我们在应用中调用PLSQL就可以一次连接关闭数据库,可以大大提高效率。

2.甲骨文官方建议:不要在程序里放任何能让数据库运行的东西。基本上在数据库中实现不会有错误,但是在程序中操作可能会有错误。(如果在数据库中操作数据,可以有日志恢复等一些功能。)

3.2。语法

CREATE OR REPLACE PROCEDURE 过程名称[(参数列表)] ISBEGIN?END [过程名称];

根据参数的类型,我们将分三类来解释它们:

l无参数

带输入参数的l

带输入输出参数(返回值)的l。

3.3。没有参数存储

3.3.1。创建存储

通过Plsql Developer或语句创建存储过程:

[示例]通过调用存储过程打印hello world

创建存储过程:

--通过调用存储过程打印hello worldCREATE OR REPLACE PROCEDURE P_HELLO ISBEGIN? DBMS_OUTPUT.PUT_LINE('hello world');?END P_HELLO;

通过工具查看创建的存储过程:

3.3.2。调用存储过程

1.通过PLSQL程序调用:

BEGIN --直接输入调用存储过程的名称 P_HELLO;?END P_HELLO;

2.在SQLPLUS中,通过EXEC命令调用:

提示:在SQLPLUS中显示结果的前提是需要设置serveroutput on。

注意:

第一个问题:is和as是互通的,用哪个都无所谓。第二个问题:过程中没有declare关键字,语句块中使用了declare。

3.4。带有输入参数的存储过程

[示例]查询并打印员工的姓名和工资(如员工编号7839)–存储过程:请求,调用时传入员工号,由控制台自动打印。

--查询并打印某个员工(如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;

命令调用:

SQL> exec p_querynameandsal(7839);姓名:KING,薪水:5000PL/SQL 过程已成功完成。

PLSQL程序调用:

BEGIN? P_QUERYNAMEANDSAL(7839);?END;

执行结果:

3.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程序调用:

DECLARE --声明一个变量接受存储过程的输出参数 V_SAL EMP.SAL%TYPE;?BEGIN? P_QUERYSAL_OUT(7839, V_SAL); --注意参数的顺序? DBMS_OUTPUT.PUT_LINE(V_SAL);?END;

注意:调用时,参数应与定义的参数的顺序和类型一致。

3.7。J***A程序调用存储过程

要求:如果一个语句不能实现结果集,比如多表查询或者复杂逻辑查询,我们可以选择调用store query来查找你的结果。

3.7.1。jdk API分析

可以通过Connection对象的prepareCall方法调用存储过程。

得出连接对象调用prepareCall方法传递一个转义的sql语句来调用存储过程,输入参数直接由set方法传递。在需要注册输出参数之后,执行存储过程并通过get方法获取。参数列表的下标从1开始。

。实现代码

准备环境:

l 导入Oracle的jar包【示例】通过员工号查询员工的姓名和薪资package cn.itcast.oracle.jdbc;?import oracle.jdbc.OracleTypes;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.DriverManager;?public class ProcedureTest { public static void ***in(String[] args) throws Exception { //1.加载驱动 Class.forName("oracle.jdbc.driver.OracleDriver");? //2.获得连接对象? //2.1 设置连接字符串 String url ="jdbc:oracle:thin:@localhost:1521:xe" ;? String name = "scott";? String password = "tiger";? Connection conn = DriverManager.getConnection(url, name, password);?? //3.获取语句对象 String sql = "{call p_querysal_out(?,?)}";//转义语法,{call 存储过程(参数列表)} CallableStatement call = conn.prepareCall(sql);? //4.设置输入参数 call.setInt(1,7839);? //5.注册输出参数 call.registerOutParameter(2, OracleTypes.DOUBLE);? //6.执行存储过程 call.execute();? //7.获取输出参数 double sal = call.getDouble(2); System.out.println("薪水:"+sal);? //8.释放资源 call.close(); conn.close();? }}

本文来自怪你过分美丽投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/544834.html

打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
() 0
上一篇 05-13
下一篇 05-13

相关推荐

  • 吉利帝豪报价及图片 吉利帝豪保养详解

    今天我们来对吉利帝豪这款车的常规保养项目价格做一个总结。官方维护手册周期表:维护价格表:质量保证政策:质保期:4年或15万公里家用汽车的保修期从**开具之日起算,法律规定不得少于3年或6万公里(以先到者为准)。维护间隔:首保里程:5000公里维护间隔:7500公里第一份保险单:厂

    2023-10-25 16:11:30
    710 0
  • 抖音极速版和抖音有什么区别 详解两个版本4大差异

    1.极限版和Tik Tok有什么区别?1、内存不同1.不同的记忆Tik Tok至尊版内存更小,流量更少,使用流畅。具有空之间小二装的特点。2.赚钱功能Tik Tok至尊版有一个赚金币的功能,可以通过看视频和邀请好友来赚钱。3.上传视频Tik Tok极速版没有视频上传功能,而带抖音的短视频可以

    2023-07-29 06:07:01
    890 0
  • 皮料用量尺寸计算公式 详解皮料采购计算攻略

    1.皮革材质可分为54寸和36寸。1英寸= 2 . 54厘米54英寸x 2.54厘米= 137.16厘米36英寸x 2.54厘米= 91.44厘米一般实际利用率135cm,一般实际利用率90cm。常宽1y = 54英寸x 91.41cm厘米= 12339(135厘米)1y = 36英寸x 91.41cm厘米= 8226(90厘米)2.工具间距:皮革打孔时,要求刀具间

    2023-07-29 03:46:01
    716 0
  • performselector实现原理 详解performselector应用场景

    RunLoop学起来很抽象,不容易理解,一定要多看几遍,多学才能学好!这也是中高级iOS必须掌握的知识点,也是面试中经常遇到的。什么是RunLoop?Run表示运行,Loop表示循环。结合在一起就是运行一个循环。RunLoop就是在程序运行过程中循环地做一些事情。RunLoop的应用类别有哪些

    2023-07-29 00:34:01
    1055 0

评论列表

联系我们

在线咨询: QQ交谈

邮件:admin@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信