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课后习题及答案 为了使得程序得代码变得简单,就需要把程序分解成较小得组成部分.有三种方法可以实现:函数.对象.模块. **** ...
随机推荐
- 【转载】MySQL索引原理及慢查询优化
原文链接:美团点评技术团队:http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型 ...
- php随机数怎么获取?一个简单的函数就能生成
小美女建了一个站,有些页面相似度比较高,想添加一些字段来实现差异化,比如用php随机数生成从10到100之间随机一个数字.其实会php的朋友几十个字符就能实现了,如下代码所示,简单吧?10代表最小值, ...
- PHP扩展迁移为兼容PHP7记录
PHP7扩展编写的时候,提供的一些内核方法和之前的PHP之前的版本并不能完全兼容.有不少方法参数做了调整.下面是在迁移过程中遇到的一些问题.记录下来,避免大家再踩坑. PHP7扩展开发之hello w ...
- MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能
MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能 Clicks: Date: -- :: Power By 李轩Lane TagMysql计数器高性能 现在有很多的项目,对计数器的实现 ...
- nginx js、css多个请求合并为一个请求(concat模块)
模块介绍 mod_concat模块由淘宝开发,目前已经包含在tengine中,并且淘宝已经在使用这个nginx模块.不过塔暂时没有包含在nginx中.这个模块类似于apache中的modconcat. ...
- Android线程消息通信(一)
Android在Java标准线程模型的基础上,提供了消息驱动机制,用于多线程之间的通信.基于消息驱动机制的线程通信模型陈伟线程消息通信.在标准线程模型中,线程执行完毕后便退出,而Android扩展了线 ...
- VMware下Ubuntu与宿主Windows共享文件夹
概述1.安装VMware Tool2.设置共享 步骤开始安装VMware Tool 显示如下画面(如果宿主无法访问外网,可能会出现一个更新失败,可以无视之) 通过下列命令解压.执行,分别是下面的tar ...
- System.getProperty()参数
java.version Java 运行时环境版本 java.vendor Java 运行时环境供应商 java.vendor.url Java 供应商的 URL java.home Java 安装目 ...
- hdu 4753 Fishhead’s Little Game 博弈论+记忆化搜索
思路:状态最多有2^12,采用记忆化搜索!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm& ...
- Codeforces Round #335 (Div. 2) C. Sorting Railway Cars 连续LIS
C. Sorting Railway Cars An infinitely long railway has a train consisting of n cars, numbered from ...