18.Oracle的过程和函数
oracle11g的过程和函数
- 一、过程(Procedure)
- 1、子程序
- 2、过程的相关语法
- 二、函数(Function)
- 1、函数的概念
- 2、函数的创建
- 3、 案例
在Oracle数据库中,过程和函数都是用来封装一系列SQL语句和逻辑操作的数据库对象,以便在需要时可以重复使用。它们都可以接受参数并返回值,但在使用上有一些区别。
zohanshu
一、过程(Procedure)
- 过程是一组SQL语句和逻辑操作的集合,它可以接受输入参数,但不一定返回数值。
- 过程可以执行数据操作、流程控制和业务逻辑,它可以包含事务控制语句,如COMMIT和ROLLBACK。
- 过程通常用于执行一系列的操作,例如数据处理、数据导入导出等。
1、子程序
-
什么是子程序
命名的 PL/SQL 块,编译并存储在数据库中。
- 子程序的各个部分:
- 声明部分
- 可执行部分
- 异常处理部分(可选)
- 子程序的分类:
- 过程 - 执行某些操作
- 函数 - 执行操作并返回值
- 子程序的各个部分:
-
子程序的优点:
- 模块化:将程序分解为逻辑模块
- 可重用性:可以被任意数目的程序调用
- 可维护性:简化维护操作
- 安全性:通过设置权限,使数据更安全
2、过程的相关语法
-
创建语法
CREATE OR REPLACE PROCEDURE procedure_name (parameter1 IN datatype1, parameter2 OUT datatype2) AS BEGIN-- 存储过程的逻辑代码 END; /在上面的语法中:
CREATE OR REPLACE用于创建或替换已存在的存储过程。PROCEDURE关键字用于声明创建一个存储过程。procedure_name是存储过程的名称。parameter1是输入参数,使用IN关键字声明,后面跟着参数的数据类型。parameter2是输出参数,使用OUT关键字声明,后面跟着参数的数据类型。AS和BEGIN之间是存储过程的实际逻辑代码。END;表示存储过程的结束。
下面是一个示例,展示了如何创建一个简单的存储过程:
CREATE OR REPLACE PROCEDURE get_employee_name (p_employee_id IN NUMBER, p_employee_name OUT VARCHAR2) AS BEGINSELECT employee_name INTO p_employee_name FROM employees WHERE employee_id = p_employee_id; END; /在上面的示例中,我们创建了一个名为get_employee_name的存储过程。它接受一个员工ID作为输入参数,并返回该员工的姓名。在实际使用时,可以通过调用这个存储过程来获取员工的姓名。
-
过程参数的三种模式
在Oracle中,存储过程和函数的参数可以使用以下三种模式进行声明和传递:
-
IN模式:
- 当参数声明为IN模式时,表示该参数是一个输入参数,即存储过程或函数可以读取该参数的值,但不能修改它。
- 在调用存储过程或函数时,需要提供IN模式参数的值作为输入。
- 例如:
CREATE OR REPLACE PROCEDURE my_procedure (p_input_param IN VARCHAR2) AS BEGIN-- 读取p_input_param的值,但不能修改它 END;
-
OUT模式:
- 当参数声明为OUT模式时,表示该参数是一个输出参数,即存储过程或函数可以修改该参数的值,并且该值将在存储过程或函数执行完毕后返回给调用者。
- 在调用存储过程或函数时,OUT模式参数通常不需要提供初始值,因为它的值将由存储过程或函数赋予。
- 例如:
CREATE OR REPLACE PROCEDURE my_procedure (p_output_param OUT NUMBER) AS BEGINp_output_param := 100; -- 修改p_output_param的值 END;
-
IN OUT模式:
- 当参数声明为IN OUT模式时,表示该参数既是输入参数,又是输出参数,即存储过程或函数可以读取并修改该参数的值,并且该值将在存储过程或函数执行完毕后返回给调用者。
- 在调用存储过程或函数时,需要提供IN OUT模式参数的初始值作为输入,并且在存储过程或函数执行完毕后,该参数的值将被修改并返回给调用者。
- 例如:
CREATE OR REPLACE PROCEDURE my_procedure (p_in_out_param IN OUT VARCHAR2) AS BEGINp_in_out_param := p_in_out_param || '_modified'; -- 修改p_in_out_param的值 END;
通过使用这三种参数模式,可以在存储过程和函数中实现对参数的不同操作和传递方式,从而满足不同的业务需求。
-
执行过程的语法
在Oracle中,执行存储过程的语法如下:EXECUTE procedure_name(parameter1, parameter2, ...);或者可以使用以下语法:
CALL procedure_name(parameter1, parameter2, ...);在上面的语法中:
- EXECUTE或CALL关键字用于执行存储过程。
- procedure_name是要执行的存储过程的名称。
- parameter1, parameter2, …是存储过程的参数,如果存储过程有参数的话,需要根据参数的顺序传递参数的值。
例如,如果有一个名为get_employee_name的存储过程,它接受一个员工ID作为输入参数,并返回员工的姓名作为输出参数,那么可以使用以下语法来执行该存储过程:
EXECUTE get_employee_name(100, :employee_name);或者使用CALL语法:
CALL get_employee_name(100, :employee_name);在上面的示例中,100是作为输入参数传递给存储过程的员工ID,:employee_name是一个输出参数,用于接收存储过程返回的员工姓名。
通过使用上述语法,可以执行存储过程并传递参数,从而实现对数据库的操作。
-
过程的执行权限授予
要将存储过程的执行权限授予其他用户,你可以使用Oracle的GRANT语句。以下是授予其他用户执行存储过程权限的示例:GRANT EXECUTE ON procedure_name TO other_user;在上面的示例中:
- procedure_name是要授予权限的存储过程的名称。
- other_user是要授予权限的其他用户的名称。
执行上述GRANT语句后,other_user将获得对procedure_name存储过程的执行权限,允许该用户执行该存储过程。
如果你希望其他用户能够执行某个schema中的所有存储过程,可以使用以下语法:
GRANT EXECUTE ON SCHEMA_NAME TO other_user;在上面的示例中,SCHEMA_NAME是包含存储过程的schema的名称,other_user将获得对该schema中所有存储过程的执行权限。
请注意,授予执行权限是一种敏感的操作,应该谨慎使用。确保只授予必要的权限,并且只授予给需要执行存储过程的用户。
二、函数(Function)
1、函数的概念
- 函数也是一组SQL语句和逻辑操作的集合。
- 函数是可以返回值的命名的 PL/SQL 子程序。
- 函数通常用于计算和返回一个值,例如在查询中调用函数来进行数学运算、字符串处理或者日期计算。
- 函数可以被用于SELECT语句的列中,也可以在其他SQL语句中调用。
在Oracle 11g数据库中,过程和函数都可以使用PL/SQL(Procedural Language/Structured Query Language)来编写,PL/SQL是Oracle数据库的过程化扩展语言,它允许开发人员在数据库中编写存储过程、函数、触发器等。
无论是过程还是函数,它们都可以提高数据库的性能和安全性,减少重复编写相同逻辑的工作,同时也可以简化数据库应用程序的开发和维护工作。
2、函数的创建
-
创捷语法
CREATE OR REPLACE FUNCTION function_name (parameter1 IN datatype1) RETURN datatype2 ASvariable datatype2; BEGIN-- 函数的逻辑代码RETURN variable; END; /在上面的语法中:
- CREATE OR REPLACE用于创建或替换已存在的函数。
- FUNCTION关键字用于声明创建一个函数。
- function_name是函数的名称。
- parameter1是输入参数,使用IN关键字声明,后面跟着参数的数据类型。
- RETURN datatype2用于声明函数的返回类型。
- AS和BEGIN之间是函数的实际逻辑代码。
- RETURN variable;用于返回函数的结果。
下面是一个示例,展示了如何创建一个简单的函数:
CREATE OR REPLACE FUNCTION calculate_bonus (p_salary IN NUMBER) RETURN NUMBER ASv_bonus NUMBER; BEGINIF p_salary > 50000 THENv_bonus := p_salary * 0.1;ELSEv_bonus := p_salary * 0.05;END IF;RETURN v_bonus; END; /以上代码是一个创建或替换函数的示例。该函数名为calculate_bonus,接受一个输入参数p_salary(工资)并返回一个数值类型的结果,表示奖金金额。
函数的逻辑如下:- 如果输入的工资p_salary大于50000,则奖金金额为工资的10%;
- 否则,奖金金额为工资的5%。
在函数体内部,使用了一个局部变量v_bonus来存储计算得到的奖金金额,并使用IF-ELSE条件语句来根据不同的情况进行计算。最后,使用RETURN语句返回计算得到的奖金金额。
通过使用上述代码,可以在数据库中创建一个名为calculate_bonus的函数,当需要根据工资计算奖金时,可以调用此函数来获得相应的奖金金额。
-
函数的限制:
- 函数的参数类型和数量必须与函数声明中的参数类型和数量匹配。
- 函数的返回类型必须与函数声明中指定的返回类型匹配。
- 函数体内部的代码必须遵循数据库管理系统所使用的特定语法和规则。
- 在函数体内部,可以访问和操作数据库表、视图、其他函数、存储过程等数据库对象,但需要确保有足够的权限来执行这些操作。
- 访问函数的两种方式:
-
直接调用:在SQL语句中可以直接调用函数,例如:
SELECT calculate_bonus(60000) FROM dual;这里的calculate_bonus是函数的名称,60000是传递给函数的参数。
-
作为表达式的一部分:函数可以作为SQL表达式的一部分来使用,例如:
SELECT employee_name, calculate_bonus(salary) AS bonus FROM employees;在这个例子中,calculate_bonus函数被用作一个表达式,用来计算每个员工的奖金,并将结果作为一个新的列返回。
通过这两种方式,可以方便地使用函数来进行计算和数据处理,从而提高数据库查询和操作的灵活性和功能性。
3、 案例
-
案例题目
已经执行了下面语句create table 分数表 (student_no number(3),name varchar2(10), score number(3));insert into 分数表 values (1,'张一', 56); insert into 分数表 values(2,'张二', 82); insert into 分数表 values (3,'张三', 90);要求:创建一个函数,可以接受用户输入的学号,得到该学生的名次,并输出这个名次。
要实现这个功能,可以创建一个函数,函数的输入参数是学生的学号,函数的输出是该学生的名次。下面是一个示例函数的定义: -
案例解答:
CREATE OR REPLACE FUNCTION get_student_rank(p_student_no IN NUMBER) RETURN NUMBER ASv_rank NUMBER; BEGINSELECT COUNT(*) INTO v_rankFROM 分数表WHERE score > (SELECT score FROM 分数表 WHERE student_no = p_student_no);RETURN v_rank + 1; -- 因为排名从1开始,所以需要加1 END; /在上面的函数中,我们创建了一个名为get_student_rank的函数,它接受一个学号作为输入参数,并返回该学生的名次。函数的逻辑如下:
- 首先,我们使用一个SELECT语句来计算比指定学生分数更高的学生数量,这个数量就是指定学生的名次。
- 然后,我们将这个名次返回作为函数的结果。
使用这个函数,可以通过以下方式获取指定学生的名次:
SELECT get_student_rank(2) FROM dual;这将返回学号为2的学生的名次。
以下对过程和函数进行的比较:
| 特性 | 过程 | 函数 |
|---|---|---|
| 返回值 | 可以有OUT参数来返回值 | 返回单个值 |
| 在SQL中的使用 | 不能直接在SQL语句中使用 | 可以直接在SQL语句中使用 |
| 错误处理 | 可以使用异常处理来处理错误 | 可以使用异常处理来处理错误 |
| 事务处理 | 可以提交或回滚事务 | 不能提交或回滚事务 |
| 调用方式 | 可以从其他过程或触发器中调用 | 可以从SQL语句或其他函数中调用 |
| CALL my_procedure(param1, param2); | SELECT my_function(param1, param2) FROM dual; |
这些是过程和函数之间的一些主要区别。根据特定任务的具体要求,每种方法都有其自己的用例和优势。
相关文章:
18.Oracle的过程和函数
oracle11g的过程和函数 一、过程(Procedure)1、子程序2、过程的相关语法 二、函数(Function)1、函数的概念2、函数的创建3、 案例 在Oracle数据库中,过程和函数都是用来封装一系列SQL语句和逻辑操作的数据库对象&#…...
A JSONObject text must begin with ‘{‘ at 1 [character 2 line 1]
今天调用一个接口,返回的是json数据,但是拿到数据进行转换的报错, JSONObject resultJson new JSONObject(resuStr);报错信息是: Exception in thread "main" org.json.JSONException: A JSONObject text must begin …...
C#中openFileDialog控件的使用方法
目录 一、OpenFileDialog基本属性 二、使用 OpenFile 从筛选的选择中打开文件 1.示例源码 2.生成效果 3. 其它示例 三、使用 StreamReader 以流的形式读取文件 1.示例源码 2.生成效果 四、一种新颖的Windows窗体应用文件设计方法 在C#中,OpenFileDialog控件…...
多线程04 死锁,线程可见性
前言 前面我们讲到了简单的线程安全问题以及简单的解决策略 其根本原因是cpu底层对线程的抢占式调度策略,随机调度 其他还有一些场景的问题如下 1.多个线程同时修改一个变量问题 2.执行的操作指令本身不是原子的 比如自增操作就分为三步,加载,自增,保存 3.内存可见性问题 4.指令…...
java中文转拼音(去除音调)
一、jar包 <dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.1</version></dependency> 二、代码 /*** 中文转换拼音*/ public class PinyinConvert {/**** param str 钱多多* r…...
[Android]常见的数据传递方式
Demo:https://github.com/Gamin-fzym/DataTransferDemo 1.Intent 发送页面 A 到页面 B 的 Intent 时,可以通过 Intent 的 putExtra() 方法将数据附加到 Intent 上。 在页面 B 中,通过 Intent 的 getXXXExtra() 方法获取传递的数据。 1).在A页面发送 …...
<蓝桥杯软件赛>零基础备赛20周--第7周--栈和二叉树
报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集 20周的完整安排请点击:20周计划 每周发1个博客,共20周(读者可以按…...
探究Kafka原理-7.exactly once semantics 和 性能测试
👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring源码、JUC源码、Kafka原理🔥如果感觉博主的文章还不错的话,请ὄ…...
【密码学引论】序列密码
第五章 序列密码 1、序列密码 定义: 加密过程:把明文与密钥序列进行异或运算得到密文解密过程:把密文与密钥序列进行异或运算得到明文以字/字节为单位加解密密钥:采用一个比特流发生器随机产生二进制比特流 2、序列密码和分组密…...
知识变现的未来:解析知识付费系统的核心
随着数字时代的发展,知识付费系统作为一种新兴的学习和知识分享模式,正逐渐引领着知识变现的未来。本文将深入解析知识付费系统的核心技术,揭示其在知识经济时代的重要性和潜力。 1. 知识付费系统的基本架构 知识付费系统的核心在于其灵活…...
【Linux基础】Linux常见指令总结及周边小知识
前言 Linux系统编程的学习我们将要开始了,学习它我们不得不谈谈它的版本发布是怎样的,谈它的版本发布就不得不说说unix。下面是unix发展史是我在百度百科了解的 Unix发展史 UNIX系统是一个分时系统。最早的UNIX系统于1970年问世。此前,只有…...
【Android知识笔记】性能优化专题(五)
App瘦身优化 随着业务迭代,apk体积逐渐变大。项目中积累的无用资源,未压缩的图片资源等,都为apk带来了不必要的体积增加。而APK 的大小会影响应用加载速度、使用的内存量以及消耗的电量。 瘦身优势: 最主要是转换率:下载转换率头部 App 都有 Lite 版渠道合作商要求了解 …...
Java基础之泛型
Java基础之泛型 一、泛型应用范围二、使用泛型方法三、泛型类 一、泛型应用范围 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。 使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序。然后,调…...
WPF实战项目十五(客户端):RestSharp的使用
1、在WPF项目中添加Nuget包,搜索RestSharp安装 2、新建Service文件夹,新建基础通用请求类BaseRequest.cs public class BaseRequest{public Method Method { get; set; }public string Route { get; set; }public string ContenType { get; set; } &quo…...
C语言基础篇5:指针(二)
接上篇:C语言基础篇5:指针(一) 4 指针作为函数参数 4.1 指针变量作为函数的参数 指针型变量可以作为函数的参数,使用指针作为函数的参数是将函数的参数声明为一个指针,前面提到当数组作为函数的实参时,值传递数组的地址…...
「Verilog学习笔记」非整数倍数据位宽转换8to12
专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网 要实现8bit数据至12bit数据的位宽转换,必须要用寄存器将先到达的数据进行缓存。8bit数据至12bit数据,相当于1.5个输入数据拼接成一个输出数据&#…...
Qt_一个由单例引发的崩溃
Qt_一个由单例引发的崩溃 文章目录 Qt_一个由单例引发的崩溃摘要关于 Q_GLOBAL_STATIC代码测试布局管理器源码分析Demo 验证关于布局管理器析构Qt 类声明周期探索更新代码获取父类分析Qt 单例宏源码 关键字: Qt、 Q_GLOBAL_STATIC、 单例、 UI、 崩溃 摘要 今…...
P8A004-系统加固-磁盘访问权限
【预备知识】 访问权限,根据在各种预定义的组中用户的身份标识及其成员身份来限制访问某些信息项或某些控制的机制。访问控制通常由系统管理员用来控制用户访问网络资源(如服务器、目录和文件)的访问,并且通常通过向用户和组授予…...
数智赋能 锦江汽车携手苏州金龙打造高质量盛会服务
作为一家老牌客运公司,成立于1956年的上海锦江汽车服务有限公司(以下简称锦江汽车),拥有1200多辆大巴和5000多辆轿车,是上海乃至长三角地区规模最大的专业旅游客运公司。面对客运市场的持续萎缩,锦江汽车坚…...
kolla-ansible 部署OpenStack云计算平台
目录 一、环境 二、安装及部署 三、测试 一、环境 官方文档:https://docs.openstack.org/kolla-ansible/yoga/user/quickstart.html rhel8.6 网络设置: 修改网卡名称 网络IP: 主机名: 网络时间协议 配置软件仓库 vim docke…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
