当前位置:文档之家› 第5章 PLSQL开发子程序和包

第5章 PLSQL开发子程序和包

第5章 PLSQL开发子程序和包
第5章 PLSQL开发子程序和包

第5章开发子程序和包

5.1子程序简介

子程序是指被命名的PL/SQL块,这种块可以带有参数,可以在不同应用中多次调用。PL/SQL有两种类型的子程序:过程和函数。其中,过程用于执行特定操作,而函数则用于返回特定数据。通过将商业逻辑和企业规则集成到PL/SQL子程序中,可以简化客户端应用的开发和维护,提高应用的性能。

5.2过程

5.2.1创建过程

过程一般用于执行一个指定的操作,可以将常用的特定操作封装成过程。

语法:

上述语法中,procedure_name用于指定过程名称,argument1、argument2等则用于指定过程的参数,IS或AS用于开始一个PL/SQL块。当指定参数数据类型时,不能指定其长度。另外,创建过程时,既可以指定输入参数(IN),又可以指定输出参数(OUT)及输入输出参数(IN OUT)。通过在过程中使用输入参数,可以将应用环境的数据传递到执行部分。通过使用输出参数,可以将执行部分的数据传递到应用环境。定义子程序参数时,如果不指定参数模式,则默认输入参数;如果需要定义输出参数,则必须指定OUT关键字;如果需要定义输入输出参数,则必须指定IN OUT关键字。以下通过示例说明创建过程和使用各种参数模式的方法。接下来我们看一下过程的创建。

1.创建无参过程

以下通过删除表中重复记录为例,说明创建该种过程的方法。

假设表tb_test中的数据如图4.1.1

创建一个无参函数,完成删除此表中重复记录的操作,如图5.1.2所示

图5.1.2 创建无参过程

过程pro_update_rec创建之后可以进行调用,在sql plus环境中可以使用call或者exec 两个命令。如果不使用exec或者call命令的话,我们也可以使用pl/sql块的方式来调用。

无参过程的调用如图5.1.2所示。

图5.1.2 无参过程的调用

图5.1.3 使用pl/sql块调用过程

2.创建in参数过程

创建过程时,可以使用输入参数将应用程序的数据传递到过程中。当为过程定义参数时,如果不指定参数模式,则默认为输入参数。另外,可以使用IN关键字显式地定义输入参数。下面以查询指定编号的员工为例说明创建该过程的方法,创建过程如图4.1.4所示。

图5.1.4 创建带有in参数过程

由图4.1.4可知,该过程pro_query_emp有一个in参数v_no。当调用该过程时,由于该参数没有默认值,所以必须提供数值,调用示例如图4.1.5所示。

图5.1.5 调用带in参数的存储过程

3.创建out参数过程

过程不仅可以用于执行特定操作,还可以输出数据。在过程输出数据时,需要使用OUT或IN OUT参数来完成。当定义输出参数时,必须提供OUT关键字。以下通过创建用于输出雇员名的过程为例,说明创建带有OUT参数的过程的方法,如图4.1.6所示。

图5.1.6 创建带有out参数的过程

由图4.1.6可知,由于在创建pro_querysal_emp时,没有为参数param_empno指定参数模式,所以该参数是输入参数;参数param_sal指定了OUT关键字,所以这个参数是输出参数。当在应用中调用该过程时,必须定义变量接收输出参数的数据。调用pro_querysal_emp 过程的示例如图4.1.7所示。

图5.1.7 调用带有out输出参数的过程

4.创建in out参数过程

创建过程时,不仅可以指定IN和OUT参数,还可以指定IN OUT参数。IN OUT参数也

称为输入输出参数,当使用此参数时,在调用过程之前需要通过变量给参数传递数据;调用结束后,Oracle会通过该变量将过程结果传递给应用。以下通过计算两个数值相除结果的过程proc_compute为例,说明在过程中使用IN OUT参数方法,如图4.1.8所示。

图5.1.8 创建带有IN OUT参数的过程

由图4.1.8可知,在过程proc_testinout中,param_num为输入输出参数。当在应用中调用该过程时,必须提供变量临时存放数值,在运算结束之后会将结果存放到这个变量中。调用proc_testinout过程的示例如图4.1.9所示。

图5.1.9 调用带有in out参数的过程

5.2.2使用过程时多参传递

在调用带有参数的子程序时,传递给形式参数(形参)的参数被称为实际参数(实参)。在过程内部,通过形参引用这些实参的值。为形参传递变量和数据可以采用位置传递、名称传递和组合传递3种方法。如果在定义参数时带有默认值,则在调用子程序时可以不为该形参提供数值。为说明多个参数传递的问题,我们编写一个计算3个整数和的过程。该过程如图4.1.10所示。

图5.1.10 创建计算三数之和的过程

1.按位置传递

按位置传递是指在调用时按参数的排列顺序依次写出实参的名称,将形参与实参关联起来进行传递。在这种方法中,形参与实参的名称是相互独立的、没有关系的,次序才重要。如果更新了一个过程的形参的次序,则对应该过程的所有调用都必须进行相应的更新,所以会增加维护应用程序的难度。使用按位置传递的方式来调用过程的示例如图4.1.11所示。

图5.1.11 按位置传递的方式来调用过程

2.按名称传递

按名称传递是指在调用时按照形参与实参的名称写出实参所对应的形参,将形参与实参关联起来进行传递。在这种方法中,形参与实参的名称是相互独立、没有关系的,名称的对应关系很重要,但次序不重要。它比按位置传递方法在书写上要复杂,如果只更新了一个过

程的形参的次序,则不需要对该过程的任何调用进行任何更新。但如果更新了一个过程的形参的名称,则对该过程的所有调用都必须进行相应的更新,会增加维护应用程序的难度。名称传递在调用子程序时指定参数,并使用关联符号“=>”为其提供相应的数值或变量。按名称传递式来调用子程序的示例如图4.1.12所示。

图5.1.12 按名称传递的方式来调用过程

3.组合传递

根据应用的需要,可以将按位置传递、按名称传递两种方法在同一调用中混合使用。但前面的实参必须使用按位置传递方法,而后面其余的实参则可以使用按名称传递的方法。按组合传递的方式来调用子程序的示例如图4.1.13所示。

图5.1.13 按组合传递的方式来调用过程

5.3函数

函数用于返回特定数据,如果在应用程序中经常需要通过执行SQL语句来返回特定数据,可以基于这些操作创建特定的函数。使用函数不仅可以简化客户端应用程序的开发和维护,还可以提高应用程序的执行性能。

语法:

Create [or replace] function function_name

(argument1 [mode1] datatype1,

argument2 [dode2] datatype2,

……)

Return datatype

is|as

声明部分

Begin

执行部分

Exception

异常处理部分

End;

在上述语法中,function_name用于指定函数名称,argument1、argument2等用于指定函数的参数。当指定参数数据类型时,不能指定其长度。RETURN子句用于指定函数返回值的数据类型,is或as用于开始一个PL/SQL块。当创建函数时,函数头部必须带有RETURN 子句,在函数体内至少需要包含一条RETURN语句。另外,当创建函数时,既可以指定输入参数(IN),又可以指定输出参数(OUT)及输入和输出参数(IN OUT)。以下通过示例来说明函数的用法。

5.3.1创建和使用函数

当创建函数时,函数既可以带有参数,又可以不带参数。以下通过创建用于产生一个随机数的函数为例,说明创建无参函数的方法,如图4.1.14所示。

图5.1.14 创建不带参数的函数

函数创建完之后,我么可以通过一个pl/sql块调用,调用过程如图4.1.15所示。

图5.1.15 无参函数的调用

在图4.1.15所示代码中,num用来接收函数的返回值。函数的使用除了在pl/sql块中调用外,还可以在sql语句中使用,如图4.1.16所示。

图5.1.16 在sql语句中使用函数

函数像过程一样可以有参数,创建函数时也可以指定in、out、in out参数。我们在使用函数的时候传入参数即可。

5.3.2函数和过程的比较

过程与函数有许多相同的功能及特性,主要包括以下4个方面:

(1)都使用IN模式的参数传入数据、OUT模式的参数返回数据。

(2)输入参数都可以接收默认值,都可以传值。

(3)调用时的实参都可以使用位置表示法或名称表示法。

(4)都有声明部分、执行部分和异常处理部分。

使用过程和函数的时机通常取决于需要从子程序中返回多少个值以及需要如何使用这些值。一般而言,返回多个值或不返回值时使用过程,只需要返回一个值时使用函数。虽然带OUT模式的参数的函数也能返回多个值,但是一般都认为这种方法属于不好的编程习惯

或风格。过程一般用于执行一个指定的动作,函数一般用于计算和返回一个值。可以在 SQL 语句内部调用函数来完成复杂计算问题,因为函数一定会有一个值通过其名称返回给调用环境;但不能调用过程,因为过程的返回值与过程的名称无关。

5.4包

包 (Package)用于组合逻辑相关的 PL/SQL类型 (例如TABLE类型和 RECORD类型)、

PL/SQL项 (例如游标和游标变量)和PL/SQL子程序 (例如过程和函数)。通过使用 PL/SQL 包,不仅可以简化应用设计、提高应用性能,还可以实现信息隐藏、子程序重载等功能。

5.4.1创建包

包由包规范和包体两部分组成。当创建包时,需要首先创建包规范,然后创建包体。

1. 创建包规范

实际上,包规范是包与应用程序之间的接口,用于定义包的公用组件,包括常量、变量、游标、过程和函数。在包规范中所定义的公用组件不仅可以在包内引用,而且可以由其他的子程序引用。创建包规范时需要注意,为了实现信息隐藏,不应该将所有组件全部放在包规范处定义,应该只定义公用组件。在SQL Plus 中创建包规范时,需要使用CREATE PACKAGE 命令来完成。

语法:

上述语法中,package_name用于指定包名,而以IS或AS开始的部分用于定义公用组件。以下通过创建用于计算圆面积的包dbutil_package为例,说明创建包规范的方法。当定义该包规范时,定义常量pi、公用过程print_area以及公用函数getarea,如图4.1.17所示。

图5.1.17 创建包规范

在执行上述命令后,就会创建包规范dbutil_package,并且定义所有的公用组件。但因为只定义了过程和函数的头部,没有编写过程和函数的执行代码,所以公用的过程和函数只有在创建了包体之后才能调用。

2.创建包体

包体用于实现包规范所定义的过程和函数。当创建包体时,也可以单独定义私有组件,包括变量、常量、过程和函数等,但在包体中定义的私有组件只能在包内使用,不能由其他子程序引用。在创建包时,为了实现信息隐藏,应该在包体内定义私有组件。为了实现包规范中所定义的公用过程和函数,必须创建包体。创建包体需要使用命令CREATE PACKAGE BODY来完成。

语法:

Create [or replace] package body package_name

IS|AS

Private type and item declarations

Subprogram bodies

End package_name;

上述语法中,package_name用于指定包名,由 IS或AS 开始的部分定义私有组件,并实现包规范中所定义的公用过程和函数。此外,包体名称与包规范名称必须相同。以下通过实现包规范dbutil_package的公用组件为例,说明创建包体的方法,如图4.1.18所示。

图 5.1.18 包体的创建

Oracle 好多项目shop项目hr人事管理项目用不同的包分类管理各项目的过程和函数......

5.4.2使用包中组件

包的私有组件只能在包内调用,并且可以直接调用;而包的公用组件既可以在包内调用,又可以在其他应用中调用。但需要注意的是,当在其他应用中调用包的组件时,必须添加包名作为前缀(包名.组件名),以下将举例说明调用包组件的方法。

1. 在同一包内调用包的组件

在调用同一包内的其他组件时,可以直接调用,不需要添加包名作为前缀。

2. 调用包的公用变量

当在其他应用中调用包的公用变量时,必须在公用变量名前添加包名作为前缀,并且其数值在当前会话内一直生效,如图4.1.19所示。

图5.1.19 调用包的公有变量

3. 调用包的公用子程序

当在其他应用中调用包的公用过程时,必须在公用过程名前添加包名作为前缀,如图4.1.20所示。

图5.1.20 调用包的公用子程序

5.5子程序和包的管理

5.5.1子程序的管理

过程与函数被存储在数据库中,可以随时查看源代码。如果需要,可以在创建过程与函数时随时查看更加详细的编译错误信息,不需要的过程与函数可以随时删除。

1. 查看子程序的源码

在创建子程序之后,Oracle会将子程序名及其源代码信息存放在数据字典中。通过查询数据字典USER_SOURCE,显示当前用户的所有子程序及其源代码,如图4.1.21所示。

图5.1.21 查看子程序的源代码

2. 删除子程序

如果不再需要某个子程序,可以将其删除。删除proc_sum过程示例如图4.1.22所示。

图5.1.22 删除过程

5.5.2包的管理

1. 查看包源代码

当创建了包之后,Oracle会将包名及其源代码信息存放到数据字典中。通过查询数据字典US_ER_SOURCE,显示当前用户的包及其源代码,包代码的查询和过程代码查看区别就在type字段,包的type字段值为”PACKAGE”,包体的type字段值为”PACKAGE BODY”。

2. 删除包

当包不再需要时,可以删除包。如果只删除包体,则可以使用DROP PACHAGE BODY命令;如果同时删除包规范和包体,则可以使用DROP PACKAGE命令。

?本章总结

?子程序包括过程和函数,过程用于执行特定操作,而函数则用于返回特定数据。

?包 (Package)用于组合逻辑相关的 PL/SQL类型 (例如TABLE类型和 RECORD类型)、PL/SQL项 (例如游标和游标变量)和PL/SQL子程序 (例如过程和函数)。

?包由包规范和包体两部分组成。当创建包时,需要首先创建包规范,然后创建包体。

任务实训部分

1:无参存储过程

训练技能点

?无参存储过程的创建和使用

需求说明

向部门表dept中插入两条部门信息,要求创建存储过程proc _ insert _ dept实现,表中原始数据如图4.2.1所示。

图5.2.1 部门表dept原始数据

实现思路

(1)创建并执行存储过程“proc _ insert _ dept”,用于向表中插入数据,如图4.2.2所示。

图5.2.2 无参存储过程

(2)调用存储过程,并查询结果如图4.2.3所示。

图5.2.3 调用存储过程

2:带IN和OUT参数的存储过程

训练技能点

?带IN和OUT参数的存储过程的创建和使用

需求说明

编写过程,命名为“proc_storage”,向该存储过程传入需要出库的商品编号和出库数量,执行出库操作并返回完成状态、商品名称、原库存和现有库存。其中“0”表示出库成功,“1”表示找不到该商品,“2”表示库存不足。原始数据表tb_storage和tb_shop初始数据如图5.2.4所示。

图5.2.4 创建表并插入测试数据

实现思路

(1)创建存储过程proc_storage,该过程包含两个IN 参数,分别用于接收需要出库的商品和出库数量;包含4个OUT参数,分别返回完成状态、商品名称、原库存和现有库存,如图5.2.5所示。

图5.2.5 创建存储过程proc_storage

(2)在PL/SQL块中测试并运行过程,如图4.2.6所示。

图5.2.6 测试并运行结果

3:带IN和OUT参数的函数

训练技能点

?创建和使用带IN和OUT参数的函数

需求说明

根据雇员名称查询雇员所在部门名称和岗位的函数。

实现思路

(1)创建函数名“fun_getEmpInfo”,该函数包含一个输入参数雇员名称param_ename、一个输出参数部门名称param_dname和一个返回值返回岗位信息。如图4.2.7所示。

oracle子程序和包

实验: 子程序和包 实验目的 (1)掌握函数和子程序的创建和使用。 (2)掌握带参数的子程序的使用。 (3)掌握包的创建和使用。 实验内容 1、编写一个包emp_package,用来对emp表进行操作。其中应包含以上几个功能: (1)编写一个不带参数的过程dept_pro,功能是输出每个部门名称和部门人数,建议使用游标。 SQL> ed 已写入file afiedt.buf 1 create procedure emp_pro 2 is 3 CURSOR dept_cur IS select dname,count(empno)人数from emp,dept 4 where emp.deptno=dept.deptno group by dname; 5 begin 6 for v_dept in dept_cur loop 7 dbms_output.put_line(v_dept.dname||' '||v_dept.人数); 8 end loop; 9* end; SQL> / 过程已创建。 (2)输入职工编号,得到职工姓名的存储过程或函数emp_pro或emp_fun CREATE OR REPLACE PROCEDURE emp_pro ( p_name OUT emp.ename%type, p_sal OUT emp.sal%type, p_eno IN emp.empno%type )

IS begin -- Test statements here select ename,sal into p_name,p_sal from emp where empno=p_eno; end; CREATE OR REPLACE FUNCTION emp_fun(p_eno emp.empno%type) RETURN emp.ename%type IS v_ename emp.ename%type; begin -- Test statements here select ename into v_ename from emp where empno=p_eno; return v_ename; end; (3)编写一个函数dept_fun,向函数传递一个部门号,如果dept表中不包含这个部门号,则返回”无此部门。 SQL> ed 已写入file afiedt.buf 1 CREATE OR REPLACE FUNCTION dept_fun(v_deptno NUMBER:=&deptno) 2 RETURN dept.dname%type 3 IS 4 v_dname dept.dname%type; 5 begin 6 -- Test statements here 7 select dname into v_dname 8 from dept where deptno=v_deptno; 9 return v_dname; 10 EXCEPTION 11 WHEN NO_DA TA_FOUND THEN 12 DBMS_OUTPUT.PUT_LINE('无此部门'); 13* end; SQL> / 输入deptno 的值: 10 原值1: CREATE OR REPLACE FUNCTION dept_fun(v_deptno NUMBER:=&deptno) 新值1: CREATE OR REPLACE FUNCTION dept_fun(v_deptno NUMBER:=10) 函数已创建。

Oracle子程序存储过程

Oracle_子程序_存储过程 select user from dual; set serveroutput on --存储过程 CREATE OR REPLACE PROCEDURE proce_Test --创建过程 is --局部变量 BEGIN dbms_output.put_line('大家好' ); END proce_Test; --执行存储过程建议按f5 执行存储过程 execute proce_test; begin proce_test; end; --------------------------------------------------------------------------------------- ----------------------------------------------- -- 此处说明定义存储过程时不能给形参施加限制(大小),存储过程创建出错,也会保留在服务器上------------------------------------------------ ------错误问题说明 Create procedure Sp_Test1(a varchar2,b out varchar2) -- 此处不能加size,执行存储过程会出错.但该存储过程依然保存在数据库中,此名字已经被占用,当修改正确后,再执行时会抱该对象已经存在的异常,所以建议使用or replace is Begin b :=a; End Sp_Test1; drop procedure sp_Test1 --create or replace procedure --test(a varchar2,b out varchar2) is --begin

ORACLE系统包介绍

Oracle 系统包 DBMS_OUTPUT a)启用 i. dbms_output.enable(buffer_size in integer default 20000); ii. set serveroutput on; b)禁用 i. dbms_output.disable; c)PUT和PUT_LINE i. PUT:所有信息显示在同一行 ii. PUT_LINE信息显示后,自动换行 d)NEW_LINE用于在行的尾部追加行结束符,一般用PUT同时使用 e)GET_LINE和GET_LINES i. DBMS_OUTPUT.GET_LINE(li ne 0UTVARCHAR2,status OUT INTEGER)用于取缓冲区的单行 信息 ii. DBMS_OUTPUT.GET_LINES(lines OUT chararr,numlies IN OUT INTEGER) 用于取得缓冲区的多行信息 DBMS_JOB a)SUBMIT用于建立一个新作业 语法 DBMS_JOB.SUBMIT( job OUT BINARY_INTEGER, what IN VARCHAR2, next_date IN DATE DEFATULT SYSDATE, interval IN VARCHAR2 DEFAULT ' NULL' , no_parse IN BOOLEAN DEFAULT FALSE, instance IN BINARY_INTEGER DEFAULT any_instance, force IN DEFAULT FALSE); 例子 VAR jobno NUMBER; BEGIN DBMS_JOB.SUBMI( :jobno, 'pro_hrs101d0_ins_hrs101t0', sysdate, ‘sysdate+1 '); b)REMOVE!于删除作业队列中的特定作业 语法:DBMS_JOB.REMOVE(jov IN BINARY_INTEGER); 例子:DBMS_JOB.REMOVE(10);--删除JOB号为10 的JOB c)CHANGE用于改变与作业相关的所有信息

子程序

第七章子程序和程序包 目标 本节课的主要目标就是了解子程序和程序包。 为什么会用到子程序? 引入 什么是子程序? 子程序就是能够接受参数并被其他程序所调用的命名PL/SQL块。PL/SQL子程序有两种类型,过程和函数。一般地,过程用于执行一个操作,而函数用于计算一个结果值。 与未命名或匿名PL/SQL块一样,子程序也有声明部分,执行部分和一个可选的异常处理部分。声明部分包含类型、游标、常量、变量、异常和嵌套子程序的声明。 子程序 子程序分为过程(store procedure)和函数(function),是一种特殊的pl/sql语句块。它以编译好的的形式存储在数据库中,可以被后来的语句块调用。 运行时是编译而不是运行,要调用才会有结果。 DML增、删、改用过程,计算用函数。 过程:没有返回值。函数:有且只有一个返回值。

子程序作用: 1、允许模块化编程 2、能够实现较快的执行过程 3、能够减少网络流量 4、可作为一种安全机制 存储过程 创建过程的语法 CREATE[OR REPLACE]PROCEDURE [()] IS|AS BEGIN [EXCEPTION ] END; 存储过程中定义的形式参数,不能指定长度,否则报错。 1.不带参数的存储过程 create or replace procedure test1 is begin

dbms_output.put_line('大家好'); end; 执行: SQL>set serveroutput on SQL>exec test1; 任何的输出都要先执行 SQL>set serveroutput on 否则就无法看到输出结果,为什么呢?任何的输出在客户端看不见,他直接往oracle服务器上去输出。执行这句让它在控制台上也输出一份。 2.带输入参数 create or replace procedure test2 ( a in number, b in varchar2 ) is begin dbms_output.put_line(a); dbms_output.put_line(b); end; 调用 SQL>exec test2(1,'a'); 1 a

内置包Oracle

内置程序包 Oracle提供了许多内置程序包,它们用于扩展数据库的功能。在开发应用程序时,可以利 用这些程序包。数据库用户SYS拥有Oracle提供的所有程序包。它们被定义为公有同义词, 并将执行权限授予了PUBLIC用户组,任何用户都可以访问它们。 Oracle提供的程序包的部分列表见表8.1。 续表 下面简单介绍几个常用的内置程序包。 8.2.1 DBMS_OUTPUT DBMS—OUTPUT程序包允许显示PL/SQL块和子程序的输出结果,这样便于测试和调试它们。 PUT和PUT_LINE过程将信息输出到SGA中的缓冲区。通过调用过程GET_LINE或通过 SET SERVEROUTPUT ON,可以显示缓冲区中的信息。 默认缓冲区大小是2000字节。最小值是2000,最大值是1,000,000。DBMS一OUTPUT包 有以下常用过程。 ENABLE

ENABLE过程用来启用对PUT、PUT_ LINE和NEW_LINE等过程的调用,它只有一个输入参数, 即缓冲区大小(BUFFER_SIZE)。缓冲区大小的输入值用于设置默认缓存的信息量。调用 ENABLE将清除任何已废弃会话中缓存的数据。 DISABLE DISABLE没有输入和输出。DISABLE用于禁用对PUT、PUT_LINE和NEW_LINE的所有调用。 调用DISABLE过程还可清除缓冲区中的任何剩余信息。 PUT PUT有一个输入参数,此参数被重载以接受VARCHAR2、NUMBER和DATE值。PUT用于在缓冲 区中存储一条信息。TO_CHAR将使用默认格式设置格式化这些项。 PUT_ LINE PUT_ LINE有一个输入参数,此参数被重载以接受VARCHAR2、NUMBER和DATE值。如果这些 值是要混合使用,则必须显式使用TO_CHAR函数。PUT_LINE过程用于将一条信息存储在缓 冲区中,后接一个行结束标记。 NEW_LINE NEW_LINE没有参数。它用于向缓冲区中添加换行符。换行符充当行结束标记。对 PUT_LINE 或NEW_LINE的每次调用都将产生一行。 例13演示了DBMS_OUTPUT包的用法。 例13: 例13的输出结果如下所示。 8.2.2DBIVIS_LOB

oracle包以及简单操作样例

一、包的概念 PL/SQL为了满足程序模块化的需要,除了块(block)和子程序结构外,还引入了包的构造。 (1)包是一种数据库对象,将逻辑上相关的PL/SQL类型、对象和子程序组合成一个更大的单位,是一组相关过程、函数、变量、常量和游标等PL/SQL程序设计元素的组合,它具有面向对象程序设计语言的特点,是对这些PL/SQL 程序设计元素的封装。 (2)包类似于C++和JAVA语言中的类,其中变量相当于类中的成员变量,过程和函数相当于类方法。把相关的模块归类成为包,可使开发人员利用面向对象的方法进行存储过程的开发,从而提高系统性能。 (3)与类相同,包中的程序元素也分为公用元素和私用元素两种,这两种元素的区别是他们允许访问的程序范围不同,即它们的作用域不同。公用元素不仅可以被包中的函数、过程所调用,也可以被包外的PL/SQL 程序访问,而私有元素只能被包内的函数和过程序所访问。 (4)PL/SQL的包具有信息隐蔽性(information hiding),仅在算法和数据结构设计有关层可见。可将过程说明和过程体组成一个程序单位。也可将过程说明与它的过程体分开,在这种情况下,将过程放置在一个包中,可隐蔽实现的细节。也可在包中定义过程,而该过程在包说明中没有定义过程说明,这样定义的过程仅在包内使用。

(5)在PL/SQL程序设计中,使用包不仅可以使程序设计模块化,对外隐藏包内所使用的信息(通过使用私用变量),而写可以提高程序的执行效率。因为,当程序首次调用包内函数或过程时,ORACLE将整个包调入内存,当再次访问包内元素时,ORACLE直接从内存中读取,而不需要进行磁盘I/O操作,从而使程序执行效率得到提高。如果ORACLE具有Procedure选件,包可以编译、存贮在ORACLE数据库中,其内容可为许多应用共享。 二、包的作用 包可以将任何出现在块声明的语句(过程,函数,游标,游标,类型,变量)放于包中,相当于一个容器。将声明语句放入包中的好处是:用户可以从其他PL/SQL块中对其进行引用,因此包为PL/SQL提供了全程变量。 三、包定义: (1)一个包由两个分开的部分组成: (2)包定义(PACKAGE):包定义部分是为应用程序的接口,声明包内数据类型、变量、常量、游标、子程序和异常错误处理等元素,这些元素为包的公有元素。

ORACLE程序包的创建与应用

ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) 本篇主要内容如下: 第七章程序包的创建和应用 7.1 程序包简介 7.2 程序包的定义 7.3 包的开发步骤 7.4 包定义的说明 7.5 子程序重载 7.6 加密实用程序 7.7 删除包 7.8 包的管理 7.1 程序包简介 程序包(PACKAGE,简称包)是一组相关过程、函数、变量、常量和游标等PL/SQL程序设计元素的组合,作为一个完整的单元存储在数据库中,用名称来标识包。它具有面向对象程序设计语言的特点,是对这些PL/SQL 程序设计元素的封装。包类似于c#和JAVA语言中的类,其中变量相当于类中的成员变量,过程和函数相当于类方法。把相关的模块归类成为包,可使开发人员利用面向对象的方法进行存储过程的开发,从而提高系统性能。 与高级语言中的类相同,包中的程序元素也分为公用元素和私用元素两种,这两种元素的区别是他们允许访问的程序范围不同,即它们的作用域不同。公用元素不仅可以被包中的函数、过程所调用,也可以被包外的PL/SQL程序访问,而私有元素只能被包内的函数和过程序所访问。 当然,对于不包含在程序包中的过程、函数是独立存在的。一般是先编写独立的过程与函数,待其较为完善或经过充分验证无误后,再按逻辑相关性组织为程序包。 程序包的优点 简化应用程序设计:程序包的说明部分和包体部分可以分别创建各编译。主要体现在 以下三个方面: 1)可以在设计一个应用程序时,只创建各编译程序包的说明部分,然后再编写引用该程序 包的PL/SQL块。 2)当完成整个应用程序的整体框架后,再回头来定义包体部分。只要不改变包的说明部分, 就可以单独调试、增加或替换包体的内容,这不会影响其他的应用程序。 3)更新包的说明后必须重新编译引用包的应用程序,但更新包体,则不需重新编译引用包 的应用程序,以快速进行应用程序的原形开发。

Fortran95实验指导 实验八 子程序

实验八 函数与子例行程序 子程序是FORTRAN95提供的重要功能之一,FORTRAN95允许用户自己定义子程序,允许用户通过子程序设计和编写程序。在设计和编写一个复杂的程序时,通常需要使用科学的程序设计方法,如:结构化程序设计方法、模块化程序设计方法、面向对象程序设计方法等,子程序功能完全支持结构化和模块化程序设计方法,结构化和模块化程序设计方法可通过子程序得到应用。使用子程序可提高程序的可读性、可理解性、可维护性和可修改性,是编写高质量、高水平、高效率程序的有效手段。 子程序分内部子程序和外部子程序。内部子程序是包含在程序单元CONTAINS 结构中的子程序,只有定义它们的程序单元才能调用执行它们。内部子程序包括函数子程序和子例行程序两类,通常将函数子程序简称为函数,子例行程序简称为子程序。 本次实验是学习和掌握子程序的一次系统实验活动。通过本次实验,能够熟练使用语句函数、内部子程序、外部子程序设计和编写程序,求解比较复杂的实际问题。 一、实验目的 1. 了解函数的有关基本概念,如:函数名称、函数自变量、函数调用、函数表达式等。 2. 掌握语句函数定义、调用、参数的基本内容和使用规则。 3. 掌握使用语句函数设计和编写程序的方法。 4. 了解内部子程序的有关基本概念,如:定义、调用、形式参数、实在参数、参数传递关系等。 5. 掌握内部子程序定义、调用、形式参数、实在参数、参数传递的基本内容和使用规则。 6. 掌握结构化程序设计方法。 7. 掌握使用内部子程序设计和编写程序的方法。 8. 了解递归概念,掌握递归问题的求解方法。 9. 掌握递归子程序定义、调用、参数传递关系的基本内容和使用规则。 10. 了解外部子程序概念,掌握并行、协调、合作编写大型复杂程序的方法。 11. 掌握外部子程序定义、调用、参数传递关系的基本内容和使用规则。 12. 掌握使用递归和外部子程序设计和编写程序的方法 二、实验内容1 1、问题描述 在解决某工程计算问题时,遇到下列函数: 2()12y x x x =++ 2 ()f x = ()p x = ()q x =计算x=0.1,0.2,0.3时,上述函数的值,并输出。使用语句函数编写程序实现之。

Oracle 程序包主体

Oracle 程序包主体 程序包主体包含了在规范中声明的过程和函数的实现代码,程序包主体的名称必须与规范的名称相同,这个相同的名称将规范与主体结合在一起组成程序包。另外,程序包主体中定义的过程和函数的名称、参数和返回值等必须与规范中声明的完全区配。创建程序包主体使用CREATE PACKAGE BODY语句如下: create [or replace] package body package_name is [pragma serially_reusable;] [collection_type_definition ...] [record_type_definition ...] [subtype_definition ...] [collection_declaration ...] [constant_declaration ...] [exception_declaration ...] [object_declaration ...] [record_declaration ...] [variable_declaration ...] [cursor_body ...] [function_spec ...] [procedure_spec ...] [call_spec ...] [begin sequence_of_statements] end [package_name] 包主体中的内容是私有的,它实现了包规范部分定义的细节内容,并且对调用者是不可见的。在包主体中有一个比较特殊的部分,即BEGIN表示的一个可选的初始化部分,它用于初始化包中的变量等。 在了解创建程序包主体的语法后,下面将为SCOTT_EMP_PKG包创建主体,实现过程UPDATE_SAL()和一个函数SELECT_NAME()。代码如下: SQL> create or replace package body scott_emp_pkg is 2 procedure update_sal(deptno_param number,sal_param number) is 3 begin 4 update emp 5 set sal=sal+sal_param 6 where deptno=deptno_param; 7 end update_sal; 8 9 function select_name(empno_param number) return varchar2 is 10 e_ename varchar2(20); 11 begin 12 select ename 13 into e_ename

包和子程序(考试复习)

第七章包和子程序 1.1目标 1.过程和函数 2.过程和函数在plsql中调用 3.包 1.2知识点 1.过程和函数的作用,语法结构,参数的类型 2.在plsql语句块中调用函数和过程 3.包和包体的作用,语法结构 1.3难点 1.过程和函数的作用,语法结构,参数的类型 2.包和包体的作用,语法结构 1.4讲解内容 前面Plsql是匿名的存储过程,可以批量执行sql操作,并且可以加入条件控制,但是每次执行的plsql脚本不能在服务器端保存,而过程和函数可以将plsql语句块按功能划分,并保存起来,实现代码的复用,简单的讲,过程和函数是对plsql语句块的封装,是有名字的plsql 语句块。 1.4.1过程 过程语法结构: Create or replace procedure存储过程名称as←创建或重定义存储过程名称, Begin 执行过程的语句块… End; ←执行语句块用begin和end包围,相当于程 序中的{},表示语句块的开始和结束

Create or replace procedure存储过程名称(参数1,参数2)as←创建或重定义存储过程名称, Begin 执行过程的语句块… End; 要点: 1.参数默认是输入参数,注明out为输出参数in out为输入输出参数 2.没有参数的过程和函数,在过程名称后面不用带()括号 3.有参数的过程和函数,形式参数的数据类型不需要指定长度 4.局部变量放在as 和begin之间,begin和end之间是plsql语句块 示例: create or replace procedure pro1 as begin dbms_output.put_line('dd'); end; create or replace procedure pro2(v_val1 in out varchar2,v_val2 in out varchar2) as begin dbms_output.put_line('v_val1:'||v_val1); dbms_output.put_line('v_val2:'||v_val2); end; 1.4.2函数 函数的语法结构 和过程类似,区别在于多了一个返回值 Create or replace function函数名称return类型as←创建或重定义函数,必须带return 和返回一个数据的类型 Begin 函数执行的语句块 return返回值←返回值,和创建函数声明中返回类型要一致 End; 示例: create or replace function fun1 return varchar2as begin return'ddd'; end;

第十章子程序与程序包

子程序与程序包
1. 子程序概述
? 什么是子程序? 一个命名的 PL/SQL 块,编译并存储在数据库中。 ? 为什么要使用子程序? 在第八,九章,我们学习了 PL/SQL 块和游标,可以在一个代码块中解 决复杂的业务逻辑,但是我们也发现,我们的代码块是临时的,只能使 用一次,如果这个业务我们需要再次使用,我们需要重新编写。基于此, 我们将要重用的业务块进行命名,存储在数据库中,这就是子程序。 ? 子程序的构成? 子程序的结构和普通的 PL/SQL 块是一致的,也包括如下部分: 声明部分 可执行部分 异常处理部分(可选) ? 子程序的分类? 存储过程 函数 ? 子程序的优点? 模块化【将程序分解为逻辑模块】 可重用性【可以被任意数目的程序调用】 可维护性【简化维护操作】 安全性【通过设置权限,使数据更安全】
2. 存储过程
过程是用于完成特定任务的子程序, 通过使用过程不仅可以简化客户端应用 程序的开发和维护,而且还可以提高应用程序的运行性能。 1) 创建存储过程的语法如下: CREATE [OR REPLACE] PROCEDURE [()]--创建过程, 可指定运行过程需传递 的参数 IS|AS --可以声明变量 BEGIN --包括在过程中要执行的语句 [EXCEPTION ] --处理异常 END; [注]过程体内不能使用查询语句,只能用于赋值(SQL 语句块都如此) 如果过程体语句有错误也能创建成功 没有参数就不写,不用()

第5章 PLSQL开发子程序和包

第5章开发子程序和包 5.1子程序简介 子程序是指被命名的PL/SQL块,这种块可以带有参数,可以在不同应用中多次调用。PL/SQL有两种类型的子程序:过程和函数。其中,过程用于执行特定操作,而函数则用于返回特定数据。通过将商业逻辑和企业规则集成到PL/SQL子程序中,可以简化客户端应用的开发和维护,提高应用的性能。 5.2过程 5.2.1创建过程 过程一般用于执行一个指定的操作,可以将常用的特定操作封装成过程。 语法: 上述语法中,procedure_name用于指定过程名称,argument1、argument2等则用于指定过程的参数,IS或AS用于开始一个PL/SQL块。当指定参数数据类型时,不能指定其长度。另外,创建过程时,既可以指定输入参数(IN),又可以指定输出参数(OUT)及输入输出参数(IN OUT)。通过在过程中使用输入参数,可以将应用环境的数据传递到执行部分。通过使用输出参数,可以将执行部分的数据传递到应用环境。定义子程序参数时,如果不指定参数模式,则默认输入参数;如果需要定义输出参数,则必须指定OUT关键字;如果需要定义输入输出参数,则必须指定IN OUT关键字。以下通过示例说明创建过程和使用各种参数模式的方法。接下来我们看一下过程的创建。

1.创建无参过程 以下通过删除表中重复记录为例,说明创建该种过程的方法。 假设表tb_test中的数据如图4.1.1 创建一个无参函数,完成删除此表中重复记录的操作,如图5.1.2所示 图5.1.2 创建无参过程 过程pro_update_rec创建之后可以进行调用,在sql plus环境中可以使用call或者exec 两个命令。如果不使用exec或者call命令的话,我们也可以使用pl/sql块的方式来调用。 无参过程的调用如图5.1.2所示。

子程序包TLM说明

******************************************************************************* 子程序LOVE1 ******************************************************************************* *计算平面外(LOVE波型)问题的特征值和特征向量(1次形函数) SUBROUTINE LOVE1(OMEGA0,NL,H,Vs,RHO,HG,BJ,N,KBETA,Y,DBETA0) *OMEGA0:圆频率 *NL:薄层数 *H:层厚H(I) *Vs:剪切波速Vs(I) *RHO:质量密度RHO(I) *HG:阻尼比HG(I) *BJ:模型底部边界条件:刚性边界:BJ=0;阻尼器边界:BJ=1;旁轴边界:BJ=2 *N:=NL *KBETA:特征值KBETA(N) *Y:特征向量Y(N,N) *DBETA0:Dβ(N)=Y T AsY[式(8-129)] USE IMSL NONE IMPLICIT NL,BJ,N INTEGER REAL*8 OMEGA0 H(NL),Vs(NL),RHO(NL),HG(NL) REAL*8 KBETA(N),Y(N,N),DBETA0(N) COMPLEX*16 AsE(2,2),GsE(2,2),ME(2,2) COMPLEX*16 *单元矩阵As 、Gs、M、Es[式(8-19)] G(NL) COMPLEX*16 COMPLEX*16 AsG(N,N),GsG(N,N),MG(N,N),EsG(N,N) *集总矩阵As 、Gs、M、Es[式(8-20)] ALPHA0(N),BETA0(N),EV AL0(N) COMPLEX*16 REAL*8 G0 I,II,J,I1,I2 INTEGER DO 10 I=1,NL G0=RHO(I)*Vs(I)*Vs(I) G(I)=G0*DCMPLX(1.0D0,2.0D0*HG(I)) 10 CONTINUE *计算单元矩阵并组装总矩阵 GsG=DCMPLX(0.0D0,0.0D0); MG=DCMPLX(0.0D0,0.0D0) EsG=DCMPLX(0.0D0,0.0D0) AsG=DCMPLX(0.0D0,0.0D0); DO 20 J=1,NL-1 GsE=DCMPLX(0.0D0,0.0D0) GsE(1,1)=G(J)/H(J) GsE(1,2)=(-1.0D0)*GsE(1,1) GsE(2,1)=GsE(1,2) GsE(2,2)=GsE(1,1) GsG(J:J+1,J:J+1)=GsG(J:J+1,J:J+1)+GsE

Oracle PlSql包(package)

Oracl e PL/SQL包(package) 目录 Oracle PL/SQL包(package) (1) 一、什么是PL/SQL包 (2) 1、PL/SQL包举例 (3) 二、PL/SQL包的优点 (5) 三、理解包说明 (5) 四、理解包体 (7) 五、包特性的例子 (8) 六、包中私有项和公有项 (14) 七、重载包级子程序 (14) 八、包STANDARD是如何定义PL/SQL环境的 (15) 九、系统包一览 (15) 1、关于DBMS_ALERT包 (15) 2、关于DBMS_OUTPUT包 (16) 3、关于DBMS_PIPE包 (16) 4、关于UTL_FILE包 (16) 5、关于UTL_HTTP包 (17) 十、包编写准则 (17)

一、什么是PL/SQL包 包就是一个把各种逻辑相关的类型、常量、变量、异常和子程序组合在一起的模式对象。包通常由两个部分组成:包说明和包体,但有时包体是不需要的。包说明(简写为spec)是应用程序接口;它声明了可用的类型、变量、常量、异常、游标和子程序,包体(Body)部分完全定义游标和子程序,并对说明中的内容加以实现。 如下例所示,我们可以认为说明部分是一个可选接口,而包体是一个"黑盒"。我们可以调试、增强或替换一个包体而不同改变接口(包说明)。 我们可以从SQL*Plus中使用CREATE PACKAGE语句来创建一个包。语法如下: CREATE [OR REPLACE] PACKAGE package_name [AUTHID {CURRENT_USER | DEFINER}] {IS | AS} [PRAGMA SERIALLY_REUSABLE;] [collection_type_definition ...] [record_type_definition ...] [subtype_definition ...] [collection_declaration ...] [constant_declaration ...] [exception_declaration ...] [object_declaration ...] [record_declaration ...] [variable_declaration ...] [cursor_spec ...] [function_spec ...] [procedure_spec ...] [call_spec ...] [PRAGMA RESTRICT_REFERENCES(assertions) ...] END [package_name]; [CREATE [OR REPLACE] PACKAGE BODY package_name {IS | AS} [PRAGMA SERIALLY_REUSABLE;]

第七章上机课子程序和程序包

子程序和程序包 目标: 能够创建子程序 能够创建程序包 第一部分指导 本阶段的重点是学习创建过程、函数和程序包,并在程序包中使用过程、函数和游标的方法。 阶段一:使用过程 需求说明: 公司的销售经理需查看月底的订单情况。如果指定订单号的状态为“c”,则所执行的过程应显示 消息“订单已确认”。如果指定订单号的状态为“p”,则所执行的过程应显示消息“订单待处理”, 否则显示“无可用状态”。创建一过程以接受销售经理输入的特定订单号,并显示订单状态。 实现思路: 创建一个过程,可以接受ORDER-NO参数。用户可使用SELECT语句从ORDER-MASTER表 中检索订单状态,并将检索到的值存储在STATUS中。如果订单状态为已确认,则向用户显示 消息“订单已确认”。如果订单状态为待处理,则显示消息“订单待处理”。如果未找到任何数 据,则显示说明此情况的消息。 参考步骤: (1)使用用户名和口令调用SQL提示符。 (2)输入下列代码。

此过程接受销售经理输入的ORDER-MASTER表中的特定订单的ORDER_NO,并根据特定订单的ORDER_NO向销售经理显示订单的状态。 要对“o001”号订单执行此过程,请输入以下命令。 如果订单状态为已确认,则此过程的输出结果为“订单已确认”。如果订单状态为待处理,则此过程的输出结果为““订单待处理””。否则输出结果为“无可用状态”。 阶段二:使用函数 需求说明: 公司人事部门工作人员经常需要根据职员的编号驱动器所在部门的名称,但部门名称在dept表中,而工作人员需要的其他所有信息都在emp表中。为了避免使用表连接,请创建函数在接受职员编号后返回职员所在部门名称。 实现思路: 创建一个名为dept-name 的函数,该函数接受一个数字类型的参数,代表职员的编号。根据职员编号从emp表中得到部门编号,再根据部门编号从dept表中检索部门名称。 参考步骤: (1)使用用户名和口令调用SQL提示符。 (2)输入以下语句创建函数。 (3)输入以下查询代码来测试函数的功能。 此查询的输出结果如下所示。

Oracle函数,包和plsql块编程实用实例

Oracle函数,包和pl/sql块编程实例 一:函数是用于返回特定的数据。 函数案例1:输入雇员姓名,返回该雇员的年薪。 create function sp_fun2(spname varchar2) return number is yearsal number(7,2);--返回一个number类型值,具体大小是number(7,2),名字是yearsal,具体类型值。 begin select sal*12+nvl(comm,0)*12 into yearsal from emp//防止为空。 where ename=spname; return yearSal; end; 函数调用: (1)SQL>var income number;--定义变量; (2)SQL>call sp_fun2('SCOTT') into :income;--调用函数into给这个值 (3)SQL>print income;--打印一下。 二:包:包用于逻辑上组合过程和函数,他有包规范和包体两部分组成。(1)创建包规范: create package sp_package is procedure update_sal (name varchar2,newsal number); function annual_income(name varchar2) return number; end; / 注释:创建一个包,声明该包包含一个sp_pro2过程和一个sp_fun2函数。 包规范只包含函数和过程的说明。但是没有过程和函数的实现代码,包体用于实现包规范中的过程和函数。 组合: . (2)创建包体:给包sp_package实现包体。 如下: create or replace package body sp_package is procedure update_sal(name varchar2,newsal number) is begin update emp set sal=newsal where ename=name; end; function annual_income(name varchar2) return number is

ORACLE 包和包体的创建和使用

create or replace package pack_one as --包头的声明 type cur is ref cursor; --定义一个动态游标,也只能是动态 type v_record is record( -- 定义一个记录类型(集合的一种) v_name emp.ename%type, v_sal emp.sal%type, v_dname dept.dname%type ); function my_fun(v_job varchar2) return cur; --定义一个方法 procedure my_pro(v_job in varchar2,my_cur2 out cur);--定义一个存储过种 end pack_one;--包头结束 create or replace package body pack_one as--创建一个包体 function my_fun(v_job varchar2) return cur--对方法的实现,注意是在包体的声明部分里操作 is my_cur cur;--声明游标,因为还是在包的部分,所以直接声明即可 sql_cur varchar2(200); begin sql_cur:='select t1.ename,t1.sal,t2.dname from emp t1,dept t2 where t1.deptno=t2.deptno and t1.job='''||v_job||'''';--拼接SQL语句,重要注意引号的使用 dbms_output.put_line(sql_cur);--可以通过输出为调试拼接好的SQL语句 open my_cur for sql_cur;--打开游标 return(my_cur);--方法有返回值,要牢记 end my_fun;--方法的实现结束 procedure my_pro(v_job in varchar2,my_cur2 out cur)--对存储过程的实现 as sql_cur varchar2(200); begin sql_cur:='select t1.ename,t1.sal,t2.dname from emp t1,dept t2 where t1.deptno=t2.deptno and t1.job='''||v_job||''''; open my_cur2 for sql_cur;--打开游标,注意,打开的是传进来的参数,即我们把游标通过参数传出给调用环境因为是out end my_pro; begin null; end pack_one;--存储实现的结束 declare--下面是对包的调用调用其中的方法 v_cur pack_one.cur;--注意这里游标类型声明的方式 my_record pack_one.v_record;--同上,注意声明方式 begin v_cur:=pack_one.my_fun('CLERK');--通过参数调过方法,传进的参数,会被接收因为是

子程序在数控编程中的应用实例

子程序在数控编程中的应用技巧 一、引言 在一个加工程序中的若干位置,假如包含有一连串在写法上完全相同或相似的内容,为了简化程序,可以把这些重复的程序段单独列出,并按一定的格式编写成子程序。主程序在执行过程中假如需要某一子程序,可以通过调用指令来调用该程序,子程序执行后又可以返回主程序,继续执行后面的程序段。子程序在数控编程中应用相当广泛。公道、正确应用子程序功能,为编写和修改加工程序带来很大方便,能大大进步工作效率。下面先容子程序的应用原则。 (1)零件上有若干处相同的轮廓外形。在这种情况下只编写一个子程序,然后用主程序调用该子程序就可以了。 (2)加工中反复出现有相同轨迹的走刀路线。被加工的零件需要刀具在某一区域内分层或分行反复走刀,走刀轨迹总是出现某一特定的外形,采用子程序比较方便,此时通常要以增量方式编程。 (3)程序的内容具有相对的独立性。在加工较复杂的零件时,往往包含很多独立的工序,有时工序之间的调整也是容许的,为了优化加工顺序,把每一个的工序编成一个独立子程序,主程序中只需加进换刀和调用子程序等指令即可。 二、子程序的应用实例与技巧 1.分层切深零件外轮廓 示例:用直径为20mm的立铣刀,加工图1所示零件。要求每次最大切削深度不超过10mm。

图1 零件之一 分析:零件在Z向厚度为40mm,根据要求,假如每次切削的深度为10mm,则需通过4次切深完成,在这四次循环切深过程中,刀具在XY平面上的运动轨迹是完全一样的。故只要把刀具在XY平面上的运动轨迹编写成子程序,主程序四次调用该子程序就可以了。参考程序及说明如表1所示。 表1 零件1的参考加工程序 2.分层切深加工槽 示例:用直径为8mm的立铣刀,加工长方形槽,刀心轨迹如图2所示,槽深6mm,要求每次切削的深度不超 过2mm。 分析:将刀心轨迹A-B-C-D-A编成子程序,主程序三次调用子程序,使槽深逐次增加,此时通常采用增量 方式编程比较方便,参考加工程序如表2所示。

相关主题
文本预览
相关文档 最新文档