第十讲 子程序和程序包
第十讲 反应器单元的仿真设计(一)
RGibbs —— 指定物流(2)
2、使用关键组分和截尾摩尔分率……
RGibbs —— 惰性物
RStoic — 示例(2)
反应和原料同示例 ( 1 ), 若反 应在恒压及绝热条件下进行,系统 总压为 0.1013 MPa, 反应器进口温度 为 950 ℃ , 当反应器出口处 CH4 转化 率为73%时,反应器出口温度是多少?
RStoic — 示例(3)
在示例(1)中增加甲烷部分氧化反应如下式:
设定反应热的计算类型(Calculation type) 和参照条件(Reference condition) : 1、不计算反应热 (Do not calculate heat of reaction) 2、计算反应热 (Calculate heat of reaction) 3、用户指定反应热 (Specify heat of reaction)
RYield —— 产率(2)
RYield —— 组分产率
选择组分产率选项时,需指定相对于 每一单位质量非惰性进料而言,各种组分 在出口物流中的相对产率。 还可以设定进料中的某些组分为不转 化为产物的惰性组分(Inert Components)。
RYield —— 组分产率(2)
RYield —— 组分映射
RStoic—化学计量反应器(2)
数控编程中子程序的定义和调用方法
数控编程中子程序的定义和调用方法
1.子程序的定义
在编制加工程序中,有时会遇到一组程序段在-个程序中多次出现,或者在几个程序中都要使用它。
这个典型的加工程序可以做成固定程序,并单独加以命名,这组程序段就称为子程序。
2.使用子程序的目的和作用
使用子程序可以减少不必要的编程重复,从而达到减化编程的目的。
主程序可以调用子程序,一个子程序也可以调用下一级的子程序。
子程序必须在主程序结束指令后建立,其作用相当于一个固定循环。
3.子程序的调用
在主程序中,调用子程序的指令是一个程序段,其格式随具体的数控系统而定,FANUC-6T 系统子程序调用格式为
M98 P--L--
式中M98--子程序调用字;
p--子程序号;
L--子程序重复调用次数。
由此可见,子程序由程序调用字、子程序号和调用次数组成。
4.子程序的返回
子程序返回主程序用指令M99,它表示子程序运行结束,请返回到主程序。
5.子程序的嵌套
子程序调用下一级子程序称为嵌套。
上一级子程序与下一级于程序的关系,与主程序与第一层子程序的关系相同。
子程序可以嵌套多少层由具体的数控系统决定,在FANUC-6T系统中,只能有两次嵌套。
过程——子程序与函数
过程——子程序与函数子程序和函数在计算机编程中扮演着非常重要的角色。
它们是用来组织和重复使用代码的机制,可以提高代码的可读性和可维护性。
虽然子程序和函数在不同的编程语言中有一些细微的差异,但它们的基本概念是相通的。
在本文中,将详细介绍子程序和函数的定义、特性和使用方法。
子程序是一个独立的代码块,可以在程序的其他地方被调用。
它可以包含一系列的语句,用来完成特定的任务。
子程序可以接受输入参数,并返回一个值。
它的调用者可以通过传递参数给子程序来交互。
函数是一种特殊的子程序。
它可以接受多个输入参数,并返回一个值。
函数通常用来实现一些特定的数学运算,或者完成一些常见的任务,比如字符串处理、日期时间计算等。
函数可以在程序的任何地方被调用,并且可以嵌套调用。
子程序和函数的主要特性包括:1.代码重用:子程序和函数可以在程序的多个地方被调用,从而实现了代码的重用性。
这可以减少代码量,提高代码的可读性和可维护性。
2.可读性:通过将一段代码封装成子程序或函数,可以提高代码的可读性。
子程序和函数的命名通常很具有描述性,能够清晰地表达其功能。
3.模块化:子程序和函数能够将程序分解为更小、更易于管理的模块。
这有助于团队协作和代码的分工。
4.参数传递:子程序和函数可以接受输入参数,并根据这些参数执行相应的任务。
这使得代码更加灵活和可定制。
5.返回值:子程序和函数可以返回一个或多个值。
返回值可以被调用者进一步处理或者用于其他计算。
6.抽象和封装:通过将一段代码封装成子程序或函数,可以隐藏其内部实现细节,使得调用者只需要关注其功能而不需要关心具体实现。
使用子程序和函数可以提高代码的质量和效率。
下面是一些常见的使用场景:1.代码重用:如果在程序的多个地方需要完成相同或类似的任务,可以将其封装成一个子程序或函数,并在需要的地方调用。
2.模块化开发:将程序拆分成多个模块,每个模块可以由一个或多个子程序或函数组成。
这样可以提高团队协作和代码的分工。
子程序——函数(共23张PPT)
k:=trunc(sqrt(x));
for m:=3 to k do
if odd(m) then {判断奇数的函数odd,布尔类型(lèixíng)}
if x mod m=0 then yy:=false; end;
begin b:=3;
{主程序 }
repeat
a:=b;
{a 为第一个素数 }
repeat
Pascal中的子程序有两种形式:函数和过程。
第二页,共二十三页。
函数(hánshù)
之前我们接触了pascal中提供的标准(biāozhǔn)函数,
如abs(),sqrt(),inc()等等,这些函数
为我们编写程序提供了很大的方便。但是这些函 数知识常用的函数,编程的时候需要自定义一些 函数。
yes:=true;
inc(b,2);
{b是a后面待求的素数}
sub(b,yes);
{调用SUB过程来确认b是否为素数 }
if yes then s:=b-a;
{如果b是素数,则求出跨度s }
until yes;
until s > = 10;
for n:=a+1 to a+10 do
write(n:6);
从上面规划的步骤看来,从步骤②到步骤⑤需处理的目标是相同的 ,因此我们可以设计(shèjì)一段子程序Max(x1,x2),以找出x1和x2
中最大的值并返回。
第四页,共二十三页。
Program Exp41; Var n1,n2,n3,n4,n5,t1 : integer;
Function max(x1,x2 : integer) : integer;
[例4.4]如果一个自然数除了1和本身,还有别的数能够整除它, 这样的自然数就是合 数。例如15,除了1和15,还有3和5能够整除,所以15是合数。14,15,16是三个连续的
pascal语法讲义-第十讲
第十讲 子程序所谓子程序(在Object Pascal中也称为例程),其实是“过程式程序设计”(又称结构化程序设计)的产物,子程序的作用,是为了贯彻“自顶向下,逐步求精”这一编程基本原则以及程序的模块化。
一、过程在子程序这一章,我们首先了解的是“过程”(procedure)。
对过程的简单理解,就是把主程序中的一段程序给拉出来,放到外面,给他一个名字。
普通的作用,是为了节省多写很多程序段的时间,同时可以使程序的结构变得清晰,增强可读性。
首先,我想问各位读者一个很没质量的问题:如何交换两个变量的值?最简单的,也是最常用的一个方法,就是找一个中间变量:也就是上面程序段中的t。
实际运用当中,如果一个程序需要很多次的交换变量,那么写这么多次t:=a;a:=b;b:=t;是会把人给烦死的。
(笔者曾经写过一个8K的程序,用了过程后程序代码立刻缩短至7K)所以,我们的自定义过程就派上用场啦。
我们来看一看写自定义过程的格式:procedure <过程名>(<参数表>);指令; {过程首部}<私有声明>begin {过程体}<语句1..n>;end;如果用自定义过程的形式去替换主程序中某些具有相同的程序段,可以节省不少的时间,并可以方便修改。
有读者会注意到一个问题,我上面都是用的“自定义过程”去描述。
其实,我们早在前几章已经使用过过程了,只不过它们是已经Pascal系统预说明的。
比如read,readln,write,writeln等,都是已经定义过的过程,称为标准过程。
而我们自己写的这些过程,被称为自定义过程。
下面我来具体说明一下自定义过程。
自定义过程由“过程首部”(head)和“过程体”组成。
过程首部的要点:I.procedure保留字,说明以下程序段是一个过程。
II.过程名。
过程名和变量名一样,是自己定义的一个标识符。
它和变量名一样,不能和保留字和已定义的过程、变量、函数冲突。
子程序及其实现方式
3.1.1.1 按值传递
按值传递指的是用对应的实参的值对形参进行初始化。想要实现按值传递的语义,我们一般 有两种实现的方式:①实际数据的传递 ,这种情况下形参和局部变量一样需要被绑定到额外 的存储空间。然后将实参的值拷贝到新分配的存储空间。因此在实参数据比较大的情况下比 如一个较大的数组,这种拷贝的代价比较高。②传递一条通往调用程序中实参的路径,这种 传递方式不需要分配额外的空间给形参,一般只是保存实参的一个地址。但是在输入型语义 的要求下,该形参必须是写保护的。否则可能会造成变量别名的副作用。
2.2 静态
静态方式指的是在程序被加载和链接之后,变量就已经被绑定到存储空间。与栈动态相 比最大的优点是效率比较高。原因是静态的没有动态的一个内存分配和释放的代价,同时更 是直接寻址。
在 C 和 C++除非变量被 static 修饰的是静态变量,否则都是栈动态的。Pascal、Ada 和 Java 只有栈动态的方式。FORTRAN 90 中用户可以自己选择是栈动态还是静态。
return *this; } Release(); this->refcount=src.refcount; this->realptr=src.realptr;
AddRef(); } //->运算符重载 T* operator ->() {
return realptr; } void AddRef() {
三、 参数传递的方法
3.1 参数传递的语义模型
参数传递方式指的是参数被传递到子程序,或者从子程序获取的方式。参数传递从语 义上讲将有三种模型:输入性、输出型和输入输出型。输入型指的是形参可以接受对应的实 参的数据。输出型指的是形参的数据可以传送到相应的实参。输入输出型指的是两者的功能 的结合。
第十讲 VHDL语言的数据类型
关系操作符
/=
不等于
任何数据类型
<VHDL语言小于的操作枚符举与(整数类o型p,e及r对a应t的o一r维数)组
>
大于
枚举与整数类型,及对应的一维数组
<=
小于等于
枚举与整数类型,及对应的一维数组
>=
一、大于逻等辑于 操作符枚举与整数类型,及对应的一维数组
逻辑操作符
AND
与
BIT,BOOLEAN,STD_LOGIC
VHDL数据类型
字符(CHARACTER)数据类型
单引号引起来,如:‘A’ ‘a’ 字符分大小写。’A’不等于’a’
字符串(STRING)数据类型
双引号引起来字符串数组,一般用于程序的提示和结果说明, VARIABLE string_yin : STRING (1 TO 7 ) ; string_yin := "a b c d" ;
end record; singal bus : iocell; bus.Enable <= ‘1’; bus.Data <= “00110110”;
用户定义的子类型
用户对已定义的数据类型,作一些范围限制而形成新的数据类型
格式: SUBTYPE 子类型名 IS 数据类型名 范围
例:SUBTYPE data IS STD_LOGIC_VECTOR(7 DOWNTO 0); SUBTYPE digit IS INTEGER RANGE 0 TO 9;
信号和变量赋值区别举例
信号赋值(非立即)
Architecture abc of example is signal tmp:std_logic; Begin process(a,b,c) begin tmp<=a; x<=c and tmp; tmp<=b; y<=c and tmp; end process; End abc;
子程序和程序包
in number )begin selecten ameintoemp name from scott.empwhere第5章 子程序和程序包子程序是已命名的 PL/SQL 块,它们存储和在数据库中,可以为它们指定参数,可以从任何 数据库客户端和应用程序中调用它们。
命名的PL/SQL 程序包括存储过程和函数, 程序包是存储过程和函数的集合。
一、子程序子程序具有声明部分、 可执行部分和可选的异常处理部分。
声明部分包含类型、 游标、常量、 变量、嵌套子程序的声明。
可执行部分包含赋值、 控制执行过程和操纵数据库的语句。
异常 处理部分包含异常处理程序。
子程序的优点。
(1 )模块化;(2)可重用性;(3)可维护性;(4)安全性; 子程序有两种类型: (1)过程;(2)函数;一般使用过程来完成某种操作,使用函数完成操作并返回值。
1、过程。
Oracle 的过程很类似sql server 中的存储过程。
他可以被赋予参数,存储在数据库中,由其 他应用程序或PL/SQL 调用。
创建过程的格式如下:SQL> create or replace procedurefin d_emp_2(emp_ no isempname varchar ( 10);emp no=emp_ no;dbms_output.put_line( excepti onwhe n no _data_fo unddbms_output.put_li ne('雇员姓名’||emp name);the n'未找到雇员姓名’);(dept_ no i max_sal oustate outisrow_co untbeginselectselect count (*) into row_countfromfrom dept no=dept_ no; dbms_output.put_li ne( dbms_output.put_li ne( state:= 'true' ; 共访问了 ’ ||row_count|| 其中最大值是’||max_sal);scott.empscott.emp'条记录’);wherewhere2、执行过程在sql 提示符下,使用execute 语句来执行过程。
子程序和程序包
⼦程序和程序包⼦程序现在我们把命名的PL/SQL块叫做⼦程序;结构没什么区别:声明,执⾏,异常;但声明也是必须的;优点:模块化;可重⽤性;可维护性;类型:1,过程,⽤于执⾏某项操作;2,函数,⽤于执⾏某项操作并返回值;过程使⽤create procedure语句创建语法:create or replace procedure[parameter list]Is|as;Begin(executable statements)End;这⾥的is|as就相当于declare;除了拥有前⾯的⼀个过程声明语句外,其他和以前的PL/SQL⼀样;参数模式:In 接受值,默认值;Out 将值返回给⼦程序的调⽤程序In out 接受值并返回已更新的值参数的书写格式:[(参数1 in|out|in out 参数类型, 参数2 in|out|in out 参数类型,…)]创建不带参数过程的例⼦:create or replace procedure xiaojiujiuasi integer;j integer;begindbms_output.put_line('print xiaojiujiu');for i in 1..9 loopfor j in 1..9 loopto_char(i)||'='||to_char(i*j)||' ');end if;end loop;dbms_output.put_line('');end loop;end;/创建的过程就象你创建的表⼀样,属于当前操作的⽤户,其他连接的⽤户将可以通过⽤户名.过程名来调⽤过程;数据字典是user_source; drop同样可以象删除表⼀样删除存储过程注意,创建过程的时候并不会执⾏过程,必须在这之后调⽤过程来执⾏;调⽤的⽅法:1, execute procedure_name(list of parameters) ⽐如execute items(‘i201’);2,可以在匿名块中调⽤;⽐如begin items(‘i201’) end;创建带参数过程的例⼦:create or replace procedure queryEmpName(sFindNo emp.EmpNo%type)assName emp.ename%type;sJob emp.job%type;beginselect ename,job into sName,sJob from empwhere empno=sFindNo;dbms_output.put_line('ID is '||sFindNo||' de zhigong name is '||sName||' gongzuo is '||sJob);exceptionwhen no_data_found thendbms_output.put_line('no data');when too_many_rows thendbms_output.put_line('too many data');when others thendbms_output.put_line('error');end;/所以,我们发现带参数的过程真正实现了运⾏的交互性;Create or replace function[parameters list]Return datatypeis|as…….注意函数和过程的输⼊参数以及函数的返回参数的定义都不能定义精度;默认的参数模式是输⼊;其实和过程完全⼀样;只是函数⼀般不会⽤输出参数,因为他本⾝就会返回数据嘛,何必慢慢地⽤参数返回数据呢;例⼦:create or replace function getName(sno varchar2)return varcharisname varchar(12);beginselect ename into name from empwhere empno=sno;return name;exceptionwhen too_many_rows thendbms_output.put_line('too many data');when others thendbms_output.put_line('error');end;/调⽤的时候必须接受返回值:declarename varchar(12);beginname:=getname('7902');dbms_output.put_line(name);end;/或者select getname(7369) from dualSelect * from emp where ename=getname(‘7369’);过程和函数的区别过程作为PL/SQL语句块来执⾏;函数作为表达式的⼀部分调⽤;在规则说明中不包含return;必须包含return;可以返回任何值;必须返回单个值;可以包含return语句,但是与函数不同,不能返回值;必须包含⾄少⼀条return;出现编译错误的时候可以show errors或者desc user_errors来调试; 创建: 调⽤: 我们发现必须使得输⼊参数和定义的顺序⼀致,但是也不⼀定要这样,可以⽤符号=>来乱序传⼊参数;但是注意,是过程定义的参数=>调⽤块的值或参数⽽不是相反,Oracle 太不懂语⾔了;⾃主事务:pragma autonomous_transaction;第⼀个事务:create or replace procedure p1as[pragma autonomous_transaction]begininsert into student values(105,'luweiyu','男');rollback;end;/第⼆个事务调⽤了第⼀个事务:create or replace procedure p2asbeginupdate student set se='⼥';p1;end;/但是我们看到的是,p1中执⾏rollback的时候把p2中的update操作也给回滚从⽽结束了事务;在as和begin中间加⼊pragma autonomous_transaction;语句⽤于表⽰p1的事务是⾃主结束的,它将不会影响调⽤它的p2的事务的结束等;程序包程序包是模块化的数据类型,游标,⼦程序,变量等数据对象的集合;包括两个部分:1,说明部分,可以只说明,类似接⼝;a) 使⽤create package进⾏创建b) 包含公⽤对象和类型c) 声明类型,变量,常量,异常,游标和⼦程序d) 可以在没有程序包主体的情况下存在2,主体,可以没有实现的主体部分;a) 使⽤create package bodyb) 包含⼦程序和游标的定义c) 包含私有声明d) 不能在没有程序包规格说明的情况下存在开发者⽤只是说明的程序包定义规则,然后由别⼈实现,他吗的接⼝思想:1,可以使⽤函数和过程的纯度来限定函数和过程的主体部分的权限;2,函数或者可以重载个⼈觉得这⾥的程序包更象是个类⽽不是前⾯所声明的对象类型;程序包不能嵌套;综合试验:定义声明:1, create or replace package student_package is2, type student_cur is ref cursor return student%rowtype;3, procedure insert_student(stu in student%rowtype);4, procedure update_student(stu student%rowtype);5, procedure delete_student(sno student.stuid%type);6, procedure select_student(stucur in out student_cur);7, function getStudentCount return number;8, end student_package;9, /定义主体:create or replace package body student_package isicount int;beginselect count(*) into icount from student where stuid=stu.stuid;if icount>0 thendbms_output.put_line('insert data is already exsist');elseinsert into student values(stu.stuid,stu.stuname,stu.se);commit;end if;exceptionwhen too_many_rows thendbms_output.put_line('insert data is already exsist');end insert_student;procedure update_student(stu student%rowtype) isicount int;beginselect count(*) into icount from student where stuid=stu.stuid;if icount>0 thenupdate student set stuname=stu.stuname,se=stu.se where stuid=stu.stuid; commit;elsedbms_output.put_line('update data not exist!');end if;end update_student;procedure delete_student(sno student.stuid%type) isicount int;beginif icount>0 thendelete from student where stuid=sno;commit;elsedbms_output.put_line('delete data not exist');end if;procedure select_student(stucur in out student_cur) is beginopen stucur for select * from student;end select_student;function getStudentCount return number isicount int;beginselect count(*) into icount from student;return icount;end getStudentCount;end student_package;/调⽤程序包:declarestu student%rowtype;beginstu.stuid:=1009;stu.stuname:='tonglei';stu.se:='f';student_package.insert_student(stu);end;/。
汇编语言——子程序
6.2.2.2 RET指令 指令 【指令格式】RET 【功能】这是子程序返回指令,必须写在子程序的指令 序列之中。根据所在的子程序的类型不同,RET指令的功能 也分为两种情况: (1)如果RET所在子程序是NEAR类型,则从堆栈中出 栈一个字(当然,SP会加2),送给IP。 (2)如果RET所在子程序是FAR类型,则先从堆栈中出 栈一个字送到IP,再出栈一个字送到CS,栈顶指SP的值加4。
cr
PROC NEAR MOV AH,2 MOV DL,13 INT 21H MOV DL,10 INT 21H RET
cr ENDP main:MOV AX,dseg MOV DS,AX LEA DX,buf MOV AH,10 INT 21H CALL cr MOV AH,1 INT 21H MOV BL,AL ;输入一个字符 ;用BL保存读入的字符 ;输入一个符号串
【解】程序段(a)中,先把AX赋值为102H,再把BX赋 值为304H,然后用ADD指令把两数相加,和为406H,结果 放在ADD指令的目的操作数AX中。 程序段(b)的前两行与(a)完全相同,AX取值102H,BX 取值304H,但在相加之前调用了子程序cr。从例6.3中cr的 具体实现方法可以知道,调用过程中寄存器AH的值被改为 2,因为INT 21H输出功能,使AL的值也被修改,变成0AH, 并且这个值一直保持到调用结束,于是“CALL cr”指令调 用子程序后,AX的值不再是调用前的102H,而变成了 20AH,当ADD指令进行两个寄存器相加时,结果是50EH, 并放到目的操作数AX中。
6.3 应用子程序进行编程
6.3.1 子程序实例
【例6.3】分析下列程序,描述它的功能。 dseg SEGMENT buf DB 80,81 DUP(0) dseg ENDS sseg SEGMENT STACK DW 64 DUP(0) sseg ENDS cseg SEGMENT ASSUME CS:cseg,DS:dseg,SS:sseg
子程序
程序
程序(procedure)是一种子程序,它能够接受不同的引数,来运行某些特别的动作。例如: printf("Hello World\n") ;函数与程序在某些编程语言中是被分开的,但是在C语言中,所有程序都是函数, 这两者被认为是相同的。这有可能造成一些副作用,特别是在回传值是void类型时。
子程序(subroutine)是一个概括性的术语,任何高级程序所调用的程序,都被称为子程序。它经常被使 用在汇编语言层级上。子程序的主体(body)是一个代码区块,当它被调用时就会进入运行。
嵌套
嵌套
为了进一步简化程序,可以让子程序调用另一个子程序,这种程序的结构称为子程序嵌套。在编程中使用较 多的是二重嵌套。
方法
在面向对象程序设计语言中,类或对象中的子程序,被称为方法(method).
调用
调用
调用子程序M98指令 指令格式:M98P__×××× 指令功能:调用子程序 指令说明:P__为要调用的子程序号。××××为重复调用子程序的次数,若只调用一次子程序可省略不写, 系统允许重复调用次数为1~9999次。
应用
ቤተ መጻሕፍቲ ባይዱ 应用
1)零件上若干处具有相同的轮廓形状,在这种情况下,只要编写一个加工该轮廓形状的子程序,然后用主程 序多次调用该子程序的方法完成对工件的加工。
2)加工中反复出现具有相同轨迹的走刀路线,如果相同轨迹的走刀路线出现在某个加工区域或在这个区域的 各个层面上,采用子程序编写加工程序比较方便,在程序中常用增量值确定切入深度。
子程序
由一个或多个语句块组成的代码
01 基本释义
03 嵌套 05 分类
目录
02 概念 04 应用 06 调用
基本信息
什么是子程序?子程序的概念
什么是子程序?子程序的概念摘要: 把可以多次调用、能够完成特定操作功能的程序段编写成独立的程序模块称为子程序,又称其为过程。
主程序与子程序之间的关系如图1 所示。
图1 主程序与子程序间的关系一、子程序特性1.重复性2.通用性3....把可以多次调用、能够完成特定操作功能的程序段编写成独立的程序模块称为子程序,又称其为过程。
主程序与子程序之间的关系如图1 所示。
图1 主程序与子程序间的关系一、子程序特性1.重复性2.通用性3.可浮动性4.可递归和可重入性二、子程序定义格式:PROCEDURE NAME PROC ATTRIBUTE ┇PROCEDURE NAME ENDP1.子程序名2.属性①NEAR②FAR。
三、子程序的设计方法子程序是程序设计中经常使用的程序结构,通过把一些固定的、经常使用的功能做成子程序的形式,可以使源程序及目标程序大大缩短,提高程序设计的效率和可靠性。
对于一个子程序,应该注意它的入口参数和出口参数。
入口参数是由主程序传给子程序的参数,而出口参数是子程序运算完传给主程序的结果。
另外,子程序所使用的寄存器和存储单元往往需要保护,以免影响返回后主程序的运行。
主程序在调用子程序时,一方面初始数据要传给子程序,另一方面子程序运行结果要传给主程序,因此,主子程序之间的参数传递是非常重要的。
四、子程序的调用和返回1.CALL 指令2.RET 指令五、现场保护与现场恢复1.现场保护与现场恢复的原因2.现场保护与现场恢复的实现(1)PUSH/POP(2)PUSHA/POPA(3)PUSHAD/POPAD六、参数传递的实现参数传递一般有四种方法实现:(1) 利用寄存器这是一种最常见方法,把所需传递的参数直接放在主程序的寄存器中传递给子程序。
(2) 利用存储单元这种参数传递方法,把所需传递的参数直接放在子程序调用指令代码之后。
若子程序和调用程序在同一源文件(同一程序模块)中,则子程序可直接访问模块中的变量,进行参数传递。
第十章子程序与程序包
子程序与程序包1. 子程序概述 什么是子程序? 一个命名的 PL/SQL 块,编译并存储在数据库中。
为什么要使用子程序? 在第八,九章,我们学习了 PL/SQL 块和游标,可以在一个代码块中解 决复杂的业务逻辑,但是我们也发现,我们的代码块是临时的,只能使 用一次,如果这个业务我们需要再次使用,我们需要重新编写。
基于此, 我们将要重用的业务块进行命名,存储在数据库中,这就是子程序。
子程序的构成? 子程序的结构和普通的 PL/SQL 块是一致的,也包括如下部分: 声明部分 可执行部分 异常处理部分(可选) 子程序的分类? 存储过程 函数 子程序的优点? 模块化【将程序分解为逻辑模块】 可重用性【可以被任意数目的程序调用】 可维护性【简化维护操作】 安全性【通过设置权限,使数据更安全】2. 存储过程过程是用于完成特定任务的子程序, 通过使用过程不仅可以简化客户端应用 程序的开发和维护,而且还可以提高应用程序的运行性能。
1) 创建存储过程的语法如下: CREATE [OR REPLACE] PROCEDURE <procedure name> [(<parameter list>)]--创建过程, 可指定运行过程需传递 的参数 IS|AS <local variable declaration> --可以声明变量 BEGIN <executable statements> --包括在过程中要执行的语句 [EXCEPTION <exception handlers>] --处理异常 END; [注]过程体内不能使用查询语句,只能用于赋值(SQL 语句块都如此) 如果过程体语句有错误也能创建成功 没有参数就不写,不用()2) 案例一【无参】 :查询出 EMP 表中工资最高的员工编号,姓名,工资 --查询出工资最高的员工编号,姓名,工资 create or replace procedure proc_one as v_no emp.empno%type; v_name emp.ename%type; v_sal emp.sal%type; begin select max(sal) into v_sal from emp; select empno,ename into v_no,v_name from emp where sal=v_sal; dbms_output.put_line('编号'||v_no||',姓名:'||v_name||'工资:'||v_sal); exception when no_data_found then dbms_output.put_line('没有找到数据'); when too_many_rows then dbms_output.put_line('数据超过一行'); end; --执行过程 Exec proc_one; Exec proc_one(); 3) 案例二 【无参】 : 将 FORD 的工资调整为 5000, 再次运行上面代码将出错, 原因是什么?如何解决。
10讲:宏汇编、C语言调用汇编
宏定义可以带参数: 例: SHIFT1 MACRO X,Y MOV CL, X SAL Y,CL ENDM 调用时: SHIFT1 2, BX;BX算术左移2位. 例: SHIFT2 MACRO X,Y,Z MOV CL, X S&Z Y,CL ENDM 调用时: SHIFT2 2, SI,HR;SI逻辑右移2位源自*作业6:P124:题3-2,
22
8.数据返回C程序时,类型不同,使用的寄 存器不同,见表3-6. 例: CHAR 型: AL LONG 型: DX,AX (二) 举例 例3-16 气泡排序用汇编;数组元素在C程序 中输入,基本程序结构如下:
17
;exm3-16.c #include “stdio.h” extren void sort(int*,int); Main() { int aa[50]; … sort(aa,n) … }
1
宏调用:用宏名(也称宏指令)。 宏扩展:汇编时,将宏指令替换成宏体。 例:源程序 汇编时 … … SHIFT MOV CL, 4 … SAL AL, CL SHIFT … MOV CA, 4 SAL AL, CL 注:与子程序一样,可以简化源程序书写, 但有区别.
2
源程序:主程序 子程序 … SHIFT PROC CALL SHIFT MOV CL, 4 … SAL AL, CL CALL SHIFT RET 宏定义与子程序的区别: 1.子程序在运行时起作用;而宏定义在汇 编时起作用. 2.相同程序,子程序省目标码,而宏定义执 行速度快.
PUBLIC 名字 [,…] 功能:定义可以被其它模块引用的全局名字. 二、外部过程的调用 主模块: EXTRN SUB-PROC:FAR CODE SEGMENT MAIN-PROC PROC FAR … CALL SUB-PROC … RET MAIN-PROC ENDP
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
10第十讲子程序和程序包西南林业大学计算机与信息科学系——鲁 宁教学目标•子程序–过程–函数•程序包–说明–主体西南林业大学计算机与信息科学系——鲁 宁子程序•命名的PL/SQL 块•子程序的各个部分–声明部分–可执行部分–异常部分(可选)•子程序退出时,声明部分的对象是本地的并且终止其存在•可以使用支持PL/SQL的任何Oracle 工具进行定义•可以在PL/SQL程序块、过程、函数和程序包中声明西南林业大学计算机与信息科学系——鲁 宁子程序的优点•模块化–将程序分解为多个逻辑模块•可重用性–子程序在被执行之后,可以在任意数目的应用程序中使用•可维护性–子程序简化了维护•具有可扩展性西南林业大学计算机与信息科学系——鲁 宁子程序的类型•过程–用于执行某项操作•函数–用于执行某项操作并返回值西南林业大学计算机与信息科学系——鲁 宁存储过程•执行特定操作的子程序•存储于数据库中并可由任意匿名块调用•能够接受参数•在参数声明中的数据类型区分符应为无限制的西南林业大学计算机与信息科学系——鲁 宁存储过程的优点•增强了数据安全性•提高了数据库性能•节省内存•提高了开发的工作效率•完整性西南林业大学计算机与信息科学系——鲁 宁存储过程•具有两个部分–说明–以关键字PROCEDURE 开始,以过程名或参数列表结束–主体–以关键字IS 开始,以关键字END 结束,后面可以跟可选过程名称西南林业大学计算机与信息科学系——鲁 宁存储过程语法•语法CREATE [OR REPLACE] PROCEDURE <过程名> [(参数1, …参数N) ] IS|AS[局部声明]BEGIN可执行语句;EXCEPTION[例外处理程序];END [<过程名>];•参数说明变量名[IN|OUT|IN OUT] 数据类型[{:= | DEFAULT} 值] 西南林业大学计算机与信息科学系——鲁 宁西南林业大学计算机与信息科学系——鲁 宁存储过程示例CREATE PROCEDURE CREATE PROCEDURE branch_sum(p_brnch branch_sum(p_brnch branch_sum(p_brnchbranch.branch_code%TYPE branch.branch_code%TYPE) IS) IS declare variables;BEGIN可执行语句;EXCEPTIONWHEN NO_DATA_FOUND THEN 语句 ;END END branch_sum branch_sum branch_sum;;西南林业大学计算机与信息科学系——鲁 宁调用存储过程•可以作为 PL/SQL 语句调用过程–示例branch_sum(branch_sum(‘‘NYK NYK’’);•可以从 SQL SQL**Plus 中调用单独的过程 •语法EXECUTE EXECUTE Procedure_name Procedure_name Procedure_name ((参数列表);•示例SQL> EXECUTE SQL> EXECUTE branch_sum(branch_sum(branch_sum(‘‘NYK NYK’’);存储过程•创建过程时,Oracle 自动执行下列步骤–编译过程–存储所编译的代码–在数据库中存储过程•PL/SQL 编译程序用于编译代码•如果发生错误,也可创建过程,但是无效•使用SHOW ERRORS 命令或下列命令查看编译错误 SELECT ** FROM USER_ERRORS;SELECT•Oracle 将编译过程装入SGA 中•其他用户也可以执行存储在SGA 中的相同过程西南林业大学计算机与信息科学系——鲁 宁存储过程•Oracle 分三个步骤执行过程–验证用户访问–如果为非法用户,则拒绝访问–验证过程有效性–如果为非法过程,则不执行–执行过程•可以通过下列方式检查过程的有效性SELECT OBJECT_NAME, OBJECT_TYPE, STATUSFROM USER_OBJECTSPROCEDURE’’;WHERE OBJECT_TYPE =WHERE OBJECT_TYPE = ‘‘PROCEDURE西南林业大学计算机与信息科学系——鲁 宁过程和函数的参数模式•IN:输入,接受值,默认模式–参数可以是一个常数、数据量、初始化变量或表达式•OUT:输出,将值返回给子程序的调用程序–参数应为一个变量;不能为一个常量或一个表达式•IN OUT:输入输出,接受值并返回已更新的值–参数应为一个变量;不能为一个常量或一个表达式–被赋值,它的值也可以对另一个变量赋值•在函数中只能使用IN模式西南林业大学计算机与信息科学系——鲁 宁西南林业大学计算机与信息科学系——鲁 宁In 参数示例Create Or Replace ProcedureProcInsertClassInfo(StrClassID ProcInsertClassInfo(StrClassID Varchar2,Varchar2, StrClassName StrClassName Varchar2) ISVarchar2) IS BeginInsert Into Insert Into ClassInfo(ClassID,ClassName ClassInfo(ClassID,ClassName ClassInfo(ClassID,ClassName)) Values(StrClassID,StrClassName Values(StrClassID,StrClassName);); end;•-- exec procinsertclassinfo('20060704','计本06');西南林业大学计算机与信息科学系——鲁 宁添加或更新记录•create or replace procedure •Procinsert_ClassInfo(StrCID Procinsert_ClassInfo(StrCID Varchar2,StrCName Varchar2) Varchar2,StrCName Varchar2)•is •RecCount RecCount int int;;•begin • Select count( Select count(**) into ) into RecCount RecCount RecCount From From From ClassInfo ClassInfo ClassInfo WhereWhere ClassID ClassID==StrCID StrCID;;• if if reccount reccount reccount>0 then>0 then • update update classinfo classinfo classinfo set set set classname classname classname==StrCName StrCName Where Where Where ClassID ClassID ClassID==StrCID StrCID;;• else• Insert into Insert into ClassInfo(ClassID,ClassName ClassInfo(ClassID,ClassName ClassInfo(ClassID,ClassName))• Values(StrCID,StrCName Values(StrCID,StrCName Values(StrCID,StrCName););• end if;• end;•/西南林业大学计算机与信息科学系——鲁 宁Out 参数示例Create Or Replace Procedure Create Or Replace Procedure ProcGetStudScore(StrStudNo ProcGetStudScore(StrStudNo ProcGetStudScore(StrStudNovarchar2,AvgScore out number )isBeginSelect Select Avg(StudScore Avg(StudScore Avg(StudScore) Into ) Into ) Into AvgScoreAvgScore From From StudScoreInfoStudScoreInfo Where Where StudNo StudNo StudNo==StrStudNo StrStudNo;; End;•--调用存储过程declareAvgScore AvgScore AvgScore number;number;beginProcGetStudScore('20010505001',AvgScore ); DBMS_OUTPUT.PUT_LINE(AvgScore DBMS_OUTPUT.PUT_LINE(AvgScore DBMS_OUTPUT.PUT_LINE(AvgScore););end;西南林业大学计算机与信息科学系——鲁 宁IN Out 参数示例Create Or Replace Procedure Create Or Replace Procedure ProcGetStudScore(StrStudNo ProcGetStudScore(StrStudNo ProcGetStudScore(StrStudNovarchar2,AvgScore in out number )isBeginDBMS_OUTPUT.PUT_LINE(AvgScore+5);Select Select Avg(StudScore Avg(StudScore Avg(StudScore) Into ) Into ) Into AvgScoreAvgScore From From StudScoreInfoStudScoreInfo Where Where StudNo StudNo StudNo==StrStudNo StrStudNo;; End;•--调用存储过程declareAvgScore AvgScore AvgScore number:=20;number:=20;BeginProcGetStudScore('20010505001',AvgScore ); DBMS_OUTPUT.PUT_LINE(AvgScore DBMS_OUTPUT.PUT_LINE(AvgScore DBMS_OUTPUT.PUT_LINE(AvgScore););end;西南林业大学计算机与信息科学系——鲁 宁Out 参数示例•create or replace procedure •Procinsert_ClassInfo(StrCID Procinsert_ClassInfo(StrCID Varchar2,StrCName Varchar2,StrMSG out varchar2) Varchar2,StrCName Varchar2,StrMSG out varchar2)•is •RecCount RecCount int int;;•begin •Select count( Select count(**) into ) into RecCount RecCount RecCount From From From ClassInfo ClassInfo ClassInfo Where Where Where ClassID ClassID ClassID==StrCID StrCID;;•if if reccount reccount reccount>0 then >0 then •update update classinfo classinfo classinfo set set set classname classname classname==StrCName StrCName Where Where Where ClassID ClassID ClassID==StrCID StrCID;;•strmsg strmsg strmsg:=':='更新成功';•else •Insert into Insert into ClassInfo(ClassID,ClassName ClassInfo(ClassID,ClassName ClassInfo(ClassID,ClassName))•Values(StrCID,StrCName Values(StrCID,StrCName Values(StrCID,StrCName););•strmsg strmsg strmsg:=':='添加成功';•end if;•end;西南林业大学计算机与信息科学系——鲁 宁调用存储过程• declare declare StrMsg StrMsg StrMsg varchar2(30); varchar2(30);• begin• procinsert_classinfo('20070704','计算机科学与技术07',strmsg);• dbms_output.put_line(strmsg dbms_output.put_line(strmsg dbms_output.put_line(strmsg););• end;西南林业大学计算机与信息科学系——鲁 宁删除存储过程•语法DROP PROCEDURE <过程名>;•示例DROP PROCEDURE DROP PROCEDURE branch_sum branch_sum branch_sum;;函数•返回值的子程序•具有一个RETURN 子句•存储于数据库中并可由任意匿名程序块调用•仅接受IN 参数•在参数声明中的数据类型区分符应为无限制的•形参不能是PL/SQL 类型西南林业大学计算机与信息科学系——鲁 宁函数的两个部分组成•说明–以关键字FUNCTION 开始,以RETURN 子句结束•主体–以关键字IS 开始,以关键字END 结束,后面可以跟可选函数名称西南林业大学计算机与信息科学系——鲁 宁西南林业大学计算机与信息科学系——鲁 宁函数语法•语法CREATE [OR REPLACE] FUNCTION <函数名> [(参数1, 1, …… 参数N) ] RETURN N) ] RETURN datatype datatype datatype IS IS [局部声明]BEGIN 可执行语句 ;[EXCEPTION][例外处理程序]END [<函数名>];•参数说明变量名 [IN] [IN] 数据类型 [{:= | DEFAULT}[{:= | DEFAULT} 值西南林业大学计算机与信息科学系——鲁 宁函数示例CREATE FUNCTION CREATE FUNCTION day_fn(mday day_fn(mday day_fn(mday NUMBER) NUMBER) RETURN CHAR IS disp_day disp_day CHAR(15); CHAR(15);BEGIN 可执行语句 ;RETURN RETURN disp_day disp_day disp_day;;EXCEPTION 语句 ;END END day_fn day_fn day_fn;;西南林业大学计算机与信息科学系——鲁 宁求N !函数Create Or Replace Function Create Or Replace Function GetJC(N GetJC(N GetJC(N int int)) RETURN Number IS k Number:=1; Begin for i in 1..N loop k:=k k:=k**i; end loop; return K; end;西南林业大学计算机与信息科学系——鲁 宁调用函数•使用 PL/SQL 语句–示例begindbms_output.put_line(getjc(5)); end;•使用 SQL 语句–语法 SELECT SELECT function_name function_name function_name((参数) FROM DUAL;–示例Select GETJC(5) from dual;西南林业大学计算机与信息科学系——鲁 宁学生成绩统计——学生答案信息表(StudAnswer)20020316003AD ACDStudNo Custor_AnsStand_Ans20020316003A AB 20020316003ABCD ABC 20020316003B B 20010404002D AD 20010404002C C 20010404002C A 20010404002ACD ACD 20010404002B B西南林业大学计算机与信息科学系——鲁 宁学生成绩信息表(StudScoreInfo)史波梅20020505009StudScoreStudName StudNo 吴边20020505008王平20020505007包云鹏20020505006胡靖萱20020505005张璐20020505004段练20020505003沈映璧20020505002陈莉20020316003李泽伟20010404002西南林业大学计算机与信息科学系——鲁 宁评分标准:错选一个全错412标准总分24ABCD BD02BC BCD 12BD B 百分制:4*100/12=3303ABD ABC 11A A 得分标准分标准答案学生答案西南林业大学计算机与信息科学系——鲁 宁学生统分函数Create Or Replace Function GetItemScore(Stand_Ansvarchar2,Custor_Ans varchar2)return int isLenCustor int:=length(Custor_Ans);beginif LenCustor>length(stand_ans) if LenCustor>length(stand_ans) or or or Custor_Ans Custor_Ans Custor_Ans IS NULL thenIS NULL then return 0;end if;for i in 1..LenCustorloopif instr(stand_ans,substr(custor_ans,i,1))=0 thenreturn 0;end if;end loop;return LenCustor;end;西南林业大学计算机与信息科学系——鲁 宁使用SQL 语句调用函数•Select Select GetItemScore('ABC','AC GetItemScore('ABC','AC GetItemScore('ABC','AC') From Dual;') From Dual;•Select Select GetItemScore('ABC','ACD GetItemScore('ABC','ACD GetItemScore('ABC','ACD') From Dual;') From Dual;•Select Select GetItemScore('AB','ABC GetItemScore('AB','ABC GetItemScore('AB','ABC') From Dual;') From Dual;--统计各题目学生正确个数•select select studno,stand_ans,custor_ans studno,stand_ans,custor_ans studno,stand_ans,custor_ans, , getitemscore(stand_ans,custor_ans getitemscore(stand_ans,custor_ans getitemscore(stand_ans,custor_ans)) from from testanswer testanswer testanswer;;西南林业大学计算机与信息科学系——鲁 宁统计学生所有题正确数和标准分•select select studno studno studno,, Sum(getitemscore(stand_ans,custor_ans Sum(getitemscore(stand_ans,custor_ans Sum(getitemscore(stand_ans,custor_ans)),)), Sum(Length(Stand_Ans Sum(Length(Stand_Ans Sum(Length(Stand_Ans)) As )) As )) As StandScoreStandScore •from from testanswertestanswer •Group by Group by StudNo StudNo StudNo;;西南林业大学计算机与信息科学系——鲁 宁计算学生得分(百分制)•select select studno studno studno,, Sum(getitemscore(stand_ans,custor_ans Sum(getitemscore(stand_ans,custor_ans))))))**100/Sum(Length(Stand_Ans)) As Sum(Length(Stand_Ans)) As StudScoreStudScore •from from testanswertestanswer •Group by Group by StudNo StudNo StudNo;;西南林业大学计算机与信息科学系——鲁 宁建立统计视图•Create Or Replace View Create Or Replace View ViewStudTotalScore ViewStudTotalScore •as•select select studno studno studno,, round (Sum(getitemscore(stand_ans,custor_ans (Sum(getitemscore(stand_ans,custor_ans))))*100/Sum(Length(Stand_Ans)),2) As 100/Sum(Length(Stand_Ans)),2) As StudScoreStudScore •from from testanswertestanswer •Group by Group by StudNo StudNo StudNo;;西南林业大学计算机与信息科学系——鲁 宁使用视图更新学生成绩表• Update Update StudScore StudScore StudScore SS Set Set S.StudScore S.StudScore S.StudScore== (select (select V.StudScore V.StudScore V.StudScoreFrom From ViewStudTotalScore ViewStudTotalScore ViewStudTotalScore VV Where Where V.StudNo V.StudNo V.StudNo==S.StudNo S.StudNo))• Where Exists(Select (Select StudNo StudNo StudNo From From From ViewStudTotalScore ViewStudTotalScore ViewStudTotalScore VV Where Where V.StudNo V.StudNo V.StudNo==S.StudNo S.StudNo))•--查看统计结果•Select Select ** From From StudScore StudScore StudScore;;西南林业大学计算机与信息科学系——鲁 宁使用Merge 合并记录•Merge Into Merge Into StudScore StudScore StudScore SS • USING USING ViewStudTotalScore ViewStudTotalScore ViewStudTotalScore V V • On ( On (S.StudNo S.StudNo S.StudNo==V.StudNo V.StudNo))•When Matched Then• Update Set• S.StudScore S.StudScore S.StudScore==V.StudScore V.StudScore;;西南林业大学计算机与信息科学系——鲁 宁删除函数•语法DROP FUNCTION <函数名>;•示例DROP FUNCTION DROP FUNCTION day_fn day_fn day_fn;;RETURN 语句•立即完成子程序的执行,并将控制返回给调用者•内置过程–不可以包含表达式–在实现过程的正常结束之前将控制返回给调用者•内置函数–必须包含表达式,并在执行时判定西南林业大学计算机与信息科学系——鲁 宁调试存储子程序•可以使用DBMS_OUTPUT 提供的程序包调试存储子程序•可以使用PUT 和 PUT_LINEPUT_LINE 语句将变量和表达式的值输出到显示器•还可以使用SHOW ERRORS 命令查看编译错误SHOW ERRORS [PROCEDURE | FUNCTION |PACKAGE] <名称>;西南林业大学计算机与信息科学系——鲁 宁西南林业大学计算机与信息科学系——鲁 宁过程与函数作为表达式的一部分调用作为 PL/SQL 语句执行必须在规格说明中包含 RETURN 子句在规格说明中不包含RETURN 子句必须返回单个值可以返回任何值必须包含至少一条RETURN 语句可以包含 RETURN 语句,但是与函数不同,它不能用于返回值函 数过 程程序包•相关对象的封装•程序包的两部分组成–程序包规格说明–声明子程序–程序包主体–定义子程序•将逻辑相关的PL/SQL 类型、对象和子程序进行分组的数据库对象•不能对它们进行调用,也不能对其传送参数或嵌套西南林业大学计算机与信息科学系——鲁 宁程序包的优点•模块化•更轻松的应用程序设计•信息隐藏•新增功能性•性能更佳•重载西南林业大学计算机与信息科学系——鲁 宁重载•程序包中的多个子程序可以具有相同的名称•它们的形参是不同的•只能位于打包的子程序中•限制–如果子程序的参数仅名称或模式不同,则不能重载–不能基于其返回类型重载子程序西南林业大学计算机与信息科学系——鲁 宁程序包说明•是一个与应用程序的接口•声明的范围对于数据库构架而言是局部的,对程序包而言是全局的•使用CREATE PACKAGE 命令进行创建•包含公用对象和类型•声明可用的类型、常量、变量、异常、游标和子程序•可以在没有程序包主体的情况下存在西南林业大学计算机与信息科学系——鲁 宁程序包说明•是使用CREATE PACKAGE 命令创建的CREATE [OR REPLACE] PACKAGE> AS<packagenamepackagename> AS-- 公共类型和对象声明-- 子程序说明END [<程序包名称>];西南林业大学计算机与信息科学系——鲁 宁西南林业大学计算机与信息科学系——鲁 宁程序包说明示例CREATE PACKAGE airlines ASTYPE TYPE flight_day_type flight_day_type flight_day_type is RECORDis RECORD (flightno flightno flight_sch.flightno%TYPE flight_sch.flightno%TYPE,, flight_day1 NUMBER(1));CURSOR CURSOR flight_cur flight_cur flight_cur RETURN RETURN RETURN flight_day_type flight_day_type flight_day_type;;disp_day disp_day CHAR(15);CHAR(15);FUNCTION FUNCTION day_fn(mday day_fn(mday day_fn(mday NUMBER) RETURN CHAR;NUMBER) RETURN CHAR;PROCEDURE PROCEDURE branch_sum branch_sum branch_sum ( ( (p_brnch p_brnch p_brnchbranch.branch_code%TYPE branch.branch_code%TYPE););END airlines;程序包主体•实现程序包说明•完全定义游标和子程序•将实现细节和私有声明从应用程序隐含•可以将其设想为“黑箱”•可被替换增强或在不更改接口的情况下被替换•可以在不重新编译调用程序的情况下对其进行更改西南林业大学计算机与信息科学系——鲁 宁程序包主体•声明范围对于程序包主体是局部的•首次引用程序包时,运行一次程序包的初始化部分•使用CREATE PACKAGE BODY 命令进行创建•包含子程序和游标的定义•包含私有声明的类型和对象•不能在没有程序包规格说明的情况下存在西南林业大学计算机与信息科学系——鲁 宁程序包主体(续)•使用 CREATE PACKAGE BODYCREATE PACKAGE BODY 命令生成CREATE [OR REPLACE] PACKAGE BODY <程序包名称> AS-- 私有类型和对象声明-- 子程序主体[BEGIN-- 初始化语句]END [<程序包名称>];西南林业大学计算机与信息科学系——鲁 宁。