代码模块化, 即将一大块代码拆成若干小块(过程), 然后就可以在其他模块调用这些模块了, 这样, 重用性更好, 也方便管理.

过程: 过程是一个可以像执行 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 过程, 函数与参数的更多相关文章

  1. Delphi过程函数传递参数的几种方式

    Delphi过程函数传递参数的几种方式  在Delphi过程.函数中传递参数几个修饰符为Const.Var.Out. 另一种不加修饰符的为默认按值传递参数. 一.默认方式以值方式传递参数 proced ...

  2. Delphi过程函数传递参数的八种方式

    今天一同事问我为什么有些过程函数里面有Var而有些没有,不解,遂到网上百度,得解.快哉,快哉. 在Delphi过程.函数中传递参数几个修饰符为Const.Var.Out.另一种不加修饰符的为默认按值传 ...

  3. 【delphi】Delphi过程、函数传递参数的八种方式

    Delphi过程函数传递参数的八种方式

  4. win32程序通过LPCREATESTRUCT中的lpCreateParams传递参数给窗口过程函数

    win32窗口程序中如果需要给窗口过程函数传递自定义参数,可以通过LPCREATESTRUCT结构体中的lpCreateParams进行传递. 创建窗口实例函数: m_hWnd = CreateWin ...

  5. Oracle过程及函数的参数模式,In、out、in out模式

    Oracle过程及函数的参数模式 In.out.in out模式 在Oracle中过程与函数都可以有参数,参数的类型可以指定为in.out.in out三种模式. 三种参数的具体说明,如下图所示: ( ...

  6. Oracle过程及函数的参数模式详解

    一.In.out.in out模式 在Oracle中过程与函数都可以有参数,参数的类型可以指定为in.out.in out三种模式. 三种参数的具体说明,如下图所示: (1)in模式 in模式是引用传 ...

  7. PHP代码审计入门(敏感函数回溯参数过程)

    最近开始啃<代码审计企业级web代码安全架构>这本书,这一章内容看了2天很多内容都理解最主要的是对PHP不熟练所以现在理解了大概 然后进行实地环境搭建最主要的是源码百度真不好找 最后找到一 ...

  8. Install Shield常用函数以及参数

    nstall Shield函数库 1  库函数综述InstallShield包含300多个内部库函数,用户可在安装脚本中调用它们来创建程序组,操作文件夹,处理目录,监督安装状态,创建对话框,操作文件及 ...

  9. 课时17:函数:Python的乐高积木

    目录: 一.创建和调用函数 二.函数的参数 三.函数的返回值 四.课时17课后习题及答案 为了使得程序得代码变得简单,就需要把程序分解成较小得组成部分.有三种方法可以实现:函数.对象.模块. **** ...

随机推荐

  1. IOS CoreData 多表查询demo解析

    在IOS CoreData中,多表查询上相对来说,没有SQL直观,但CoreData的功能还是可以完成相关操作的. 下面使用CoreData进行关系数据库的表与表之间的关系演示.生成CoreData和 ...

  2. 【bzoj1013】[JSOI2008]球形空间产生器sphere

    1013: [JSOI2008]球形空间产生器sphere Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4530  Solved: 2364[Subm ...

  3. 录制iphone手机视频

    1: 升级自己的手机到ios8, 同时mac os也要升级到10.10 2: 用usb数据线将手机连上电脑. 3: 打开quicktime player创建新movie 4: 选择手机作为音频.视频源 ...

  4. python 小试牛刀之信息管理

    这个是之前写的半成品,但是一直没有好好的写完,今晚我把它补充完整,并且贴出了遇到的问题 这个程序并没有处理中文,主要是python 2.7对于中文的支持太蛋疼了,虽然可以设置utf8编码,但是如果列表 ...

  5. 持久化消息队列memcacheq的安装配置

    MemcacheQ 是一个基于 MemcacheDB 的消息队列服务器. 一.memcacheq介绍 特性: 1.简单易用 2.处理速度快 3.多条队列 4.并发性能好 5.与memcache的协议兼 ...

  6. How Big Is A Petabyte, Exabyte, Zettabyte, Or A Yottabyte?

    一个关于Byte递增的描述,蛮有趣的! Bytes -> Kilobyte -> Megabyte -> Gigabyte -> Terabyte -> Petabyte ...

  7. String、StringBuilder

    public class testString{ public static void main(String[] args) { String a="cool"; String ...

  8. Extjs整体加载树节点

    Ext.onReady(function () {             Ext.define('company', {                 extend: 'Ext.data.Mode ...

  9. linux 全自动提权 exp perl脚本

    linux 全自动提权 exp perl脚本 作者: admin 日期: 2013/01/19发表评论 (0) 查看评论   国外流传过来的 地址 http://dl.packetstormsecur ...

  10. c#知识库同步的总结

    C#知识库下载地址: http://www.51aspx.com/Code/FileCollector 新版下载地址:http://pan.baidu.com/s/1P3Hk 对于这一款平时用来收集知 ...