oracle as 不可以省略,Oracle:存储过程,存储函数
什么是存储过程和存储函数:指存储在数据库中供所有用户程序调用的子程序叫做存储过程、存储函数。
这个子程序是用PL/SQL写的。可以用Java程序调用,就是完成特定功能的子程序。
用create procedure命令创建存储过程。
语法:
Create [or replace] procedure 过程名(参数列表) asPLSQL子程序体;
As相当于declare,所以我们可以在as后面定义变量。As不可以省略。
--打印Hello World。
Create or replace procedure sayHelloWorld
As
--说明部分
Begin
Dbms_output.put_line(‘HelloWorld’);
End;
/
先将存储过程编译,在SQL Developer左边的树结构中的过程里就产生了这个存储过程。
如果图标上有小红叉,表示有语法错误,如果是绿叶,表示没有问题。这个存储过程的功能是打印HelloWorld。
如何调用这个存储过程呢?
第一种方式:使用execute命令
Exec sayHelloWorld();
第二种调用方式:
Begin
sayHelloWorld();
sayHelloWorld();
sayHelloWorld();
end;
/
带参数的存储过程:
--给指定员工的工资涨100元工资,并且打印涨前和涨后的薪水。
--既然是指定,就是员工会变化,所以要接收一个员工参数。
--指定参数的时候要分为输入参数和输出参数,默认是输入参数,但是显示指出比较好,用in指出。
Create or replace procedure raiseSalary(enoin number)
As
--变量
Psalemp.sal%type;
Begin
--得到涨前的薪水。
Selectsal into psal from emp where empno = eno;
--涨100元
Updateemp set sal = sal + 100 where empno = eno;
--这里不要提交事务,谁调用谁来提交事务
--打印涨前和涨后的薪水。
Dbms_output.put_line(‘涨前:’||psal||’涨后’||(psal+100));
End;
/
编译。
调用:
Begin
raiseSalary(7839);
raiseSalary(7566);
commit;
end;
/
存储过程和存储函数的区别:
存储过程没有返回值,存储函数可以有一个返回值。
存储函数:
函数为一命名的存储程序,可以带参数,并返回一个计算值。函数和过程的结构类似,但必须有一个return子句,用于返回函数值。函数说明要指定函数名、结果值的类型,以及参数类型等。
语法:
Create [or replace] function 函数名(参数列表)
Return 函数值类型
As
PLSQL子程序体;
--查询某个员工的年收入,通过函数查询,查询完将查询结果返回。
--接收一个员工参数
Create or replace functionqueryEmpIncome(eno in number)
Return number
As
--年收入与月薪和奖金有关,定义两个变量,接收月薪和奖金。
Psalemp.sal%type;
Pcommemp.comm%type;
Begin
--得到该员工的月薪和奖金
Selectsal,comm into psal,pcomm from emp where empno = eno;
--返回年收入
Returnpsal*12+nvl(pcomm,0);
End;
/
编译一下,在左边的树结构中就出现了函数的部分。
直接在图标上点右键选择运行就可以运行。
打开对话框,传参数:
控制台结果:
双击函数,可以打开一个窗口,这个窗口有debug的功能,在侧边双击可以打断点。
Debug需要权限,需要授权。
Grant DEBUG CONNECT SESSION , DEBUG ANY PROCEDUREto scott;
关于输出参数:
存储过程和存储函数都可以通过out指定一个或多个输出参数。我们可以利用out参数,在过程和函数中实现返回多个值。
原则:如果只有一个返回值,用存储函数,否则,就用存储过程。
--out参数的例子。查询并返回某个员工的姓名 月薪 职位
--因为要返回姓名,月薪,职位,就要在参数中定义为输出参数。
Create or replace procedurequeryEmpInfo(eno in number,pename out varchar2,psal out number,pjob outvarchar2)
As
Begin
Selectename,sal,empjob into pename,psal,pjob from emp where empno = eno;
End;
/
编译,在过程上刷新,右键运行。
如何在Java程序中调用存储过程或存储函数呢?
先获取Connection,在获取CallableStatement(Statement的子类)。
通过Connection的prepareCall(String sql)方法创建CallableStatement。
CallableStatement是用来执行SQL存储过程的接口。JDBCAPI提供了一个存储过程SQL转义语法,该语法允许对所有RDBMS使用标准方式调用存储过程。
调用的SQL语法:
调存储函数:?=call[(,,…)]
掉存储过程:call[(,…)]
调用示例:用PL/SQL比直接使用SQL调用效率要高。
创建工程,导入Oracle的jar包。Jar包位置如地址栏所示。
(1)JDBC工具类
Public class JDBCUtils {
Private static String driver = “oracle.jdbc.OracleDriver”;
Private static String url = “jdbc:oracle:thin:@localhost:1521:orcl”;
Private static String user = “scott”;
Private static String password = “tiger”;
Static {
Try{
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
Public static Connection getConnection() {
Try{
Return DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
e.printStackTrace();
}
Return null;
}
Public static void release(Connection conn,Statement st, ResultSet rs) {
If(rs != null) {
Try{
Rs.close();
} catch(SQLException e) {
e.printStackTrace();
} finally {
Rs = null; //为是么置null呢?需要垃圾回收,gc机制。
}
}
If(st != null) {
Try{
st.close();
} catch(SQLException e) {
e.printStackTrace();
} finally {
st = null;
}
}
If(conn != null) {
Try{
conn.close();
} catch(SQLException e) {
e.printStackTrace();
} finally {
conn = null;
}
}
}
}
Public class TestOracle {
@Test
Public void testProcedure() {
//第一个是输入参数,后三个是输出参数。
String sql = “{call queryEmpInfo(?,?,?,?)}”;
Connection conn = null;
CallableStatement call = null;
Try {
Conn = JDBCUtils.getConnection();
Call = conn.prepareCall(sal);
//对于in参数赋值
Call.setInt(1,7839);
//对于out参数。在执行后才有值。通过OracleTypes中的常量可以将Oracle的类型转换成Java的类型
Call.registerOutParameter(2,OracleTypes.VARCHAR);
Call.registerOutParameter(3,OracleTypes.NUMBER);
Call.registerOutParameter(4,OracleTypes.VARCHAR);
//执行
Call.execute();
//取出结果。
String name = call.getString(2);
double sal = call.getDouble(3);
String job = call.getString(4);
System.out.println(name);
System.out.println(sal);
System.out.println(job);
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(conn,call,null);
}
}
@Test
Public void testFunction(){
String sql = “{?=call queryEmpIncone(?)}”;
Connection conn = null;
CallableStatement call = null;
Try {
Conn = JDBCUtils.getConnection();
Call = conn.prepareCall(sal);
//第一个参数是返回值,先处理out参数
//对于out参数。在执行后才有值。通过OracleTypes中的常量可以将Oracle的类型转换成Java的类型
Call.registerOutParameter(1,OracleTypes.NUMBER);
//对于in参数赋值
Call.setInt(2,7839);
//执行
Call.execute();
//取出结果。
double income = call.getDouble(1);
System.out.println(income);
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(conn,call,null);
}
}
}
--返回某个部门的所有员工的所有信息。这样out就太多了
--可以通过在光标中定义。
在out中使用光标,有一个要求,必须将光标和存储过程或者存储函数放到一个包里面。
什么是包?
是一个数据库对象,是包头,包头只负责声明,包体只负责实现。
声明包:
--例:根据员工的员工号查询员工信息,要求返回员工的所有信息。
Create or replace package MYPACKAGE as
--自定义一个类型empcursor,这个类型引用cursor光标类型,也就是说,设个empcursor类型就是一个光标
Type empcursoris ref cursor;
--在out中使用自定义的光标类型
Procedurequeryemp(eid in number,empinfo out empcursor);
End MYPACKAGE;
什么是包体?
也是一个数据库对象,包体要实现存储过程和存储函数。
CREATE OR REPLACE
PACKAGE BODY MYPACKAGE AS
PROCEDUREqueryemp(eid in number,empinfo out empcursor) AS
BEGIN
Openempinfo for select * fro emp where empno = eid;
ENDqueryemp;
END MYPACKAGE;
--返回某个部门的所有员工的所有信息
CREATE OR REPLACE
PACKAGE MYPACKAGE AS
Typeempcursor is ref cursor;
ProcedurequeryEmpList(dno in number,empList out empcursor);
END MYPACKAGE;
--编译好后,在左边的树结构中的程序包节点中就有了刚定义的包。右键,可以选择创建包体。
--会将包头中所有需要实现的程序都列出来。
CREATE OR REPLACE
PACKAGE BODY MYPACKAGE AS
ProcedurequeryEmpList(dno in number,empList out empcursor) AS
BEGIN
--这里open了光标,并没有关闭光标,其实光标关闭了,
--因为在返回rs结果集后,程序关闭了rs,关闭了rs也就关闭了光标。
OpenempList for select * from emp where deptno = dno;
ENDqueryEmpList;
END MYPACKAGE;
//编写测试程序
@Test
Public void testCursor() {
String sql = “{call MYPACKAGE.queryEmpList(?,?)}”;
Connection conn = null;
CallableStatement call = null;
ResultSet rs = null;
Try{
Conn = JDBCUtils.getConnection();
Call = conn.prepareCall(sql);
//对于in参数赋值。部门号
Call.setInt(1,10);
//对于out参数,所有员工的所有信息。
Call.registerOutParameter(2,OracleTypes.CURSOR);
//执行。
Call.execute();
//取出该部门中的员工的信息。Call中没有getCursor,需要转成OracleCallableStatement
Rs = (OracleCallableStatement)call.getCursor(2);
While(rs.next()) {
String name = rs.getString(“ename”);
double sal = rs.getDouble(“sal”);
System.out.println(name + “ ” + sal);
}
} catch(Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(conn,call,rs);
}
}
上面的程序可以在MySQL中跑吗?不可以,因为实现的是Oracle的接口。
oracle as 不可以省略,Oracle:存储过程,存储函数相关推荐
- Oracle学习2 视图 索引 sql编程 游标 存储过程 存储函数 触发器
---视图 ---视图的概念:视图就是提供一个查询的窗口,来操作数据库中的数据,不存储数据,数据在表中. ---一个由查询语句定义的虚拟表.---查询语句创建表 create table emp as ...
- 视图存储过程存储函数
文章目录 视图 常见数据库对象 视图概述 为什么使用视图? 视图的理解 创建视图 创建单表视图 创建多表联合视图 基于视图创建视图 查看视图 更新视图的数据 一般情况 不可更新的视图 修改.删除视图 ...
- Day463.视图存储过程存储函数 -mysql
视图 1. 常见的数据库对象 对象 描述 表(TABLE) 表是存储数据的逻辑单元,以行和列的形式存在,列就是字段,行就是记录 数据字典 就是系统表,存放数据库相关信息的表.系统表的数据通常由数据库系 ...
- WebDay18 MySQL存储过程 存储函数 触发器 事务
MySQL存储过程 存储函数 触发器 事务 一.MySQL存储过程和函数 1.存储过程和函数的概念 2.存储过程和函数的好处 3.存储过程和函数的区别 4.创建存储过程 5.调用存储过程 6.查看存储 ...
- MySQL 案例实战--MySQL数据库 存储过程 存储函数
MySQL数据库 存储过程 & 存储函数 前言 一.什么是存储过程 & 存储函数 二.存储过程的创建和调用 三.存储函数的创建和调用 前言 本环境是基于 Centos 7.8 系统构建 ...
- Oracle 中重新编译无效的存储过程, 或函数、触发器等对象(转)
Oracle 中的存储过程在有些情况下会变成失效状态,在 PL/SQL Developer 中该存储过程的图标左上角显示一把小红叉叉.比如储过程所引用的对象失效,dblink 出问题啦都可能引起用到它 ...
- [mysql]存储过程/存储函数
[Stored Procedure /Stored Function] 存储过程 定义 语法分析: 调试 效果比较 存储函数 应用 语法分析: 两者对比 存储过程和函数的查看.修改.删除 查看 修改 ...
- 存储过程存储函数得简记(转)
oracle中的存储过程和存储函数的区别 (尊重劳动成果,转载请注明出处:https://blog.csdn.net/qq_39778516/article/details/84033710 cons ...
- mysql 函数 局部变量_MySQL 存储过程 存储函数 局部变量 游标 概念示例
一个存储过程是一个可编程的函数,它可以在MySQL中创建并保存.它是由一些SQL语句和一些特殊的控制结构语句组成. 当希望在不同的应用程序或平台上执行相同的函数,或者封装特定的功能时,存储过程是一个非 ...
最新文章
- shardingjdbc全局表_sharding-jdbc实现按年分库按月分表
- 想学python有什么用-Python为什么这么火?学习python有什么用?
- Python 【抖音】短视频的自动上传与发布实例演示,同时支持快手、哔哩哔哩、小红书、微视、西瓜视频、微信视频号等平台的视频自动化同步发布
- 阿里云ECS服务器搭建wordpress个人博客网站【详细图文教程】
- 机器人学中的一些概念3——雅克比矩阵
- 行政管理对计算机的要求,信息技术对行政管理的影响.doc
- PL/SQL Developer 登录 Oracle 12c和Win10下安装Oracle 11g
- win11玩游戏怎么样 windows11玩游戏的具体性能介绍
- 堆叠顺序的误区和z-index
- 【HDOJ】1071 The area
- Atitit nlp 自然语言处理的艺术 attilax著作 v2 t55.docx Atitit nlp 自然语言处理attilax总结 目录 1.1. 主要范畴	1 1.2. 研究难点
- EtherCAT总线运动控制学习笔记(RXXW_Dor)
- ubuntu安装openpose
- Excel将汉字与英文分开
- r5 5500u和r5 4600u区别有多大 r55500u和r54600u哪个好
- 10万行代码电商项目
- 文本分类 之 基于BertForSequenceClassification模型的金融知道 最佳答案推荐
- python中numpy函数ftt_语音MFCC提取:librosa python_speech_feature(2019.12)
- IDX20803: Unable to obtain configuration from: ‘[PII is hidden
- c语言学生学籍管理程序,C语言实现简单学籍管理系统
热门文章
- 紫金农商银行java面试_【应届本科生求职】我的南京紫金农商行面试之路
- python写excel文件出错_【求教】xlutils修改中文Excel文件出错
- private访问权限java_Java之访问权限
- 由MAC地址在18字节及6字节之间的转换引发越界问题讨论
- 国际计算机语言,国际标准的5种PLC编程语言简介
- aliyun maven 添加jar_gradle添加阿里云maven库
- cpci检索为什么那么慢_索引原理与慢查询优化
- logic回归是一种线性回归
- php 跳转网页 变量,php变量与JS变量实现不通过跳转直接交互的方法
- word 段显示在页面最下方_Word你说的白是什么白