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课后习题及答案 为了使得程序得代码变得简单,就需要把程序分解成较小得组成部分.有三种方法可以实现:函数.对象.模块. **** ...
随机推荐
- ios获取远程json数据
NSMutableArray *arr; arr = [[NSMutableArray alloc]init];//全局 NSURL *url = [NSURL URLWithString:@&quo ...
- Maven在项目中的应用
http://192.168.0.253:8081/nexus/#view-repositories;thirdparty~uploadPanel 使用局域网搭建的环境,输入用户名和密码登录,上传ja ...
- python模拟shell
import fileinput import readline raw_input(xxx) exec filepinput.input
- ssh-copy-id(双机互信)
最简单的2步骤: ssh-keygen -t rsa 需要输入的地方就回车 ssh-copy-id root@192.168.0.10 详细:ssh-keygen 创建公钥和密钥. ssh-copy- ...
- Server Library [Apache Tomcat v6.0](unbound)服务未绑定解决办法
(1) 单击File按钮---钩选Show AllWizard——>选择Server——>单击Next (2)Add Library 选择 WTP Server Runtime(My ...
- 2013 ACM/ICPC Asia Regional Online —— Warmup
1003 Rotation Lock Puzzle 找出每一圈中的最大值即可 代码如下: #include<iostream> #include<stdio.h> #inclu ...
- sql主键的一点重要理解
sql只会读取数据,不会自动设置主键,所以绑定数据后要设置主键(前台) 不管是int或者uniqueidentifier只要类型对得上就可以用,int自增其实没什么太大优势(但是通常都会用自增来做,从 ...
- Compile a native C Android application
原文: Compile a native C Android application翻译: Zhiwei.Li 通过上网搜索,你可以发现很多种编译Android native应用的方法.我想说的是,不 ...
- MongoDB (九) MongoDB 投影
mongodb 投影意思是只选择必要的数据而不是选择一个文件的数据的整个.如果一个文档有5个字段,需要显示只有3个,然后选择其中只有3个字段. find() 方法 MongoDB 的find()方法, ...
- Spring框架学习之第9节
aop编程 aop(aspect oriented programming)面向切面(方面)编程,是所有对象或者是一类对象编程,核心是(在不增加代码的基础上,还增加新功能) 汇编(伪机器指令 mov ...