plsql programming 17 过程, 函数与参数
代码模块化, 即将一大块代码拆成若干小块(过程), 然后就可以在其他模块调用这些模块了, 这样, 重用性更好, 也方便管理.
过程: 过程是一个可以像执行 PL/SQL 语句一样调用的程序, 一个过程可以执行一个或多个动作. 我们可以通过参数列表向过程传递或者从过程传出信息.
函数: 函数是一个通过RETURN 语句返回数据的程序, 使用起来就像是一个 PL/SQL 表达式. 我们可以通过参数列表传入参数, 也可以通过参数列表传出参数, 不过通常情况下这么做并不好.
数据库触发器: 触发器是当数据库中发生了某些事件时, 所触发执行的一系列命令
包: 一个由若干函数, 过程, 类型以及变量一起组成的并被命名的集合.
过程
PROCEDURE [schema.]name[(parameter, parameter...)]
[AUTHID DEFINE | CURRENT_USER] -- 运行时, 是用定义者权限运行, 还是用当前用户权限运行(前一种叫定义者权限模式, 后一种叫调用者权限模式)
IS
[declare]
BEGIN
executable statement;
EXCEPTION
exception handlers
END [name];

create or replace procedure apply_discount(
company_id_in in company.company_id%type,
discount_in in number)
is
min_discount constant number := .05;
max_discount constant number := .25;
invalid_discount exception;
begin
if discount_in between min_discount and max_discount then
update item
set item_amount := item_amount * (1-discount_in);
where EXISTS(select 'x' from order where order.order_id = item.order_id
and order.company_id = company_id_in);
if sql%rowcount = 0 then
raise no_data_found;
end if;
else
raise invalid_discount;
end if;
exception
when invalid_discount then
dbms_output.put_line('The specified discount is invalid.'); when no_data_found then
dbms_ouput.put_line('No orders in the system for company:' ||
to_char(company_id_in));
end apply_discount;
/
show errors;
-- 调用一个 procedure
一个过程是作为一个可执行的PL/SQL语句调用的, 换句话说, 过程调用必须以分号; 结尾, 可以在 pl/SQL 代码块的可执行单元中的其他SQL或者PLSQL语句(如果有的话)之前后调用
BEGIN
apply_discount(new_company_id, 0.15); -- 在begin 与end 之间不用 exec 就可以执行
END;
函数









-- 调用函数
DECLARE
v_nickname VARCHAR2(100) := favorite_nickname('Steven');
-- 也可以在查询, 或者表达式语句中直接调用函数
-- 如果参数的类型是 out 的, 唯一的好处就是这个函数可以返回多个值通过这些out类型的参数, 而
-- return 语句只能返回一个值
-- 提示, out 或 in out 模式应该只出现在 procedure 过程中, 函数所要返回的全部信息都应该通过 RETURN 子句返回
参数调用模式
in : 只读的, 在模块内部可以使用实参的值, 但是不能修改. 如果你没有指定参数模式, 默认就是 IN 模式
out: 只写的, 模块内部可以给参数赋值, 但是参数值不能被使用
in out: 可读写, 模块内既可以使用(读), 也可以修改(写)参数的值



只能放在赋值语句的右边






只能放在赋值语句的左边
所以, out 类型必须要传实参进去, 而且还的是个变量, 设想一下, 如果不传实参, 那么这个plsql执行完了以后, out模式的返回值返回给谁?


可以放在赋值语句的任何一边
提示: OUT 或者 IN OUT 模式的形参只应该出现在过程的定义中(而非函数), 函数所要返回的全部信息只应该通过RETURN子句来返回, 而不应该通过这两种参数. 如果能够遵守这个指导原则进行设计, 你的子程序就很容易被理解和使用了, 另外, 不能再一个SQL语句中调用带有OUT或者INOUT模式参数的函数.


命名表示法是有好处的:
1. 命名表示法是自我说明的
2. 为我们提供了有关参数规范的完整灵活性( 比如有些过程是有缺省函数的, 而你传参是又不想全部传进去, 比如有10个参数, 你只想传3个, 剩下的就用缺省参数值, 那么这种表示法, 你只要写3个参数就可以了, 这是位置表示法没法实现的)







考虑 out, 和 In out 的运行机理, 会在模块内部做一个参数的变量的拷贝, 知道过程运行成功后, 才将这个拷贝赋值给OUT变量, NOCOPY 顾名思义, 不做这个 拷贝.
缺省值 ( in 类型参数)
参数的缺省值和声明变量时指定缺省值一样, 例如:
create or replace procedure astrology_reading(
sign_in IN varchar2 := 'LIBRA',
born_at_in IN DATE DEFAULT SYSDATE)
IS
上边例子中的两个参数都有缺省值.
局部或者潜逃模块
局部模块或者嵌套模块 是 一个在PL/SQL块(不管是匿名还是命名的)的声明部分定义的过程或者函数. 之所以把这种模块叫做局部的, 是因为这种模块只在父PL/SQL块中定义, 它不能被它所在的包围块之外的块调用.

创建局部过程或者函数的语法和创建单独模块的语法完全一样, 比如:
declare
procedure show_date(date_in IN DATE) -- 内部模块
is
begin
dbms_output.put_line(to_char(date_in, 'Month dd, yyyy'));
end show_date;
begin
-- ...
end;













提示: 重载的另一个名字是静态多态. 术语多态是指语言能够定义并且选择性的使用多个具有相同名字的程序中的一个的能力, 如果该使用哪一个程序的决定是在编译时刻就确定下来的, 就叫静态多态, 如果决定是在运行时刻才确定下来的, 就叫动态多态(java), 动态多态是通过对象类型的继承得到的.



看来还是参数个数不同, 或者参数类型不同(整个家族都不同), 重载比较靠谱.

如果一个模块A调用模块B, 而同时模块B又调用模块A, 这种相互递归, 声明就会有问题, 这是就可以使用前置声明

因为第一个函数要调用第二个函数, 所以需要声明, 否则它就无法认识第2个函数.
所谓前置声明, 只是将两个互相递归调用的函数之一比如A, 把声明部分拿到最前边先声明, 然后是函数B的定义(引用了A), 然后再是A的定义(引用了B)

plsql programming 17 过程, 函数与参数的更多相关文章
- Delphi过程函数传递参数的几种方式
Delphi过程函数传递参数的几种方式 在Delphi过程.函数中传递参数几个修饰符为Const.Var.Out. 另一种不加修饰符的为默认按值传递参数. 一.默认方式以值方式传递参数 proced ...
- Delphi过程函数传递参数的八种方式
今天一同事问我为什么有些过程函数里面有Var而有些没有,不解,遂到网上百度,得解.快哉,快哉. 在Delphi过程.函数中传递参数几个修饰符为Const.Var.Out.另一种不加修饰符的为默认按值传 ...
- 【delphi】Delphi过程、函数传递参数的八种方式
Delphi过程函数传递参数的八种方式
- win32程序通过LPCREATESTRUCT中的lpCreateParams传递参数给窗口过程函数
win32窗口程序中如果需要给窗口过程函数传递自定义参数,可以通过LPCREATESTRUCT结构体中的lpCreateParams进行传递. 创建窗口实例函数: m_hWnd = CreateWin ...
- Oracle过程及函数的参数模式,In、out、in out模式
Oracle过程及函数的参数模式 In.out.in out模式 在Oracle中过程与函数都可以有参数,参数的类型可以指定为in.out.in out三种模式. 三种参数的具体说明,如下图所示: ( ...
- Oracle过程及函数的参数模式详解
一.In.out.in out模式 在Oracle中过程与函数都可以有参数,参数的类型可以指定为in.out.in out三种模式. 三种参数的具体说明,如下图所示: (1)in模式 in模式是引用传 ...
- PHP代码审计入门(敏感函数回溯参数过程)
最近开始啃<代码审计企业级web代码安全架构>这本书,这一章内容看了2天很多内容都理解最主要的是对PHP不熟练所以现在理解了大概 然后进行实地环境搭建最主要的是源码百度真不好找 最后找到一 ...
- Install Shield常用函数以及参数
nstall Shield函数库 1 库函数综述InstallShield包含300多个内部库函数,用户可在安装脚本中调用它们来创建程序组,操作文件夹,处理目录,监督安装状态,创建对话框,操作文件及 ...
- 课时17:函数:Python的乐高积木
目录: 一.创建和调用函数 二.函数的参数 三.函数的返回值 四.课时17课后习题及答案 为了使得程序得代码变得简单,就需要把程序分解成较小得组成部分.有三种方法可以实现:函数.对象.模块. **** ...
随机推荐
- *args和**kw魔法参数
学Python挺久了,现在才搞懂这个还是有点惭愧 *args:传入元组,无关键字 **kw:传入字典,有关键字 示例: *args **kw 一起使用时args的参数需在前:
- vi/vim使用指北 ---- Moving Around in a Hurry
上一篇文章中,简单列出了一些基本的Vim操作,也列出了很多的光标移动命令,本章主要是有哪些命令可以更快的移动光标. vim的编辑操作,用得最多就是移动光标,对于很少行的文件来说,基本的命令就够用了,但 ...
- 使用Rails 4.2+ 测试异步邮件系统
[导读]异步测试总是一个很大的问题,邮件发送测试更是让很多开发同学不知道从哪里入手.在新版的Rails里,这类测试在很大程度上被简化了. 以下为译文 在编写需要发送邮件的应用时,控制器是绝不能被阻塞的 ...
- 判断一个字符串在至多删除k个字符后是否为回文串
转自: http://www.careercup.com/question?id=6287528252407808 问题描述: A k-palindrome is a string which tra ...
- [你必须知道的.NET]第三十二回,,深入.NET 4.0之,Tuple一二
发布日期:2009.06.01 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. Tuple,是函数式编程的概念之一,早见于Elang.F#等动态 ...
- Struts2 直接返回字符串(可用于json)
struts2可以在method中直接返回一个字符串而不是视图.让Action中的返回字符串的方法,直接return null;并在return之前用输出流输出字符串就可以了,跟servlet输出HT ...
- iphone 异常捕获处理
iphone 异常捕获处理 1 void UncaughtExceptionHandler(NSException *exception) { 2 NSArray *arr = [exception ...
- mp3 音频 音乐 tag ID3 ID3V1 ID3V2 标签 读取信息 获得图片 jpeg bmp 图片转换等
mp3 音频 音乐 tag ID3 ID3V1 ID3V2 标签 读取信息 获得图片 jpeg bmp 图片转换(上) MP3文件格式(二)---ID3v2 图:ID3V1标签结构 图:ID3V2标签 ...
- Android核心分析 之九Zygote Service
Zygote Service 在本章我们会接触到这两个单词: Zygote [生物] 受精卵, 接合子, 接合体 Spawn:产卵 通过这两个单词,我们就可以大体知道Zygote是干什么的了,就是叫老 ...
- JavaWeb项目开发案例精粹-第6章报价管理系统-03Dao层
1. package com.sanqing.dao; import java.io.Serializable; import java.util.LinkedHashMap; import com. ...