存储过程的特点
发布时间:2020-12-12 15:51:13 所属栏目:MsSql教程 来源:网络整理
导读:?存储过程的特点? Sybase?的存储过程是集中存储在?SQL?Server?中的预先定义且已经编译好的事务。存储过程由SQL语句和流程控制语句组成。它的功能包括:接受参数、调用另一过程、返回一个状态值给调用过程或批处理、指示调用成功或失败、返回若干个参数值给调
?存储过程的特点?
Sybase?的存储过程是集中存储在?SQL?Server?中的预先定义且已经编译好的事务。存储过程由SQL语句和流程控制语句组成。它的功能包括:接受参数、调用另一过程、返回一个状态值给调用过程或批处理、指示调用成功或失败、返回若干个参数值给调用过程或批处理、为调用者提供动态结果、在远程SQL?Server中运行等。? ? 存储过程的性能特点如下: ·存储过程是预编译过的,这就意味着它与普通的?SQL?语句或批处理的?SQL?语句不同,当首次运行一个存储过程时,SQL?Server?的查询处理器对其进行分析,在排除了语法错误之后形成存储在系统中的可执行方案。由于查询处理的大部分工作已经完成,所以存储过程执行速度很快。? ·存储过程和待处理的数据都放在同一台运行?SQL?Server?的计算机上,使用存储过程查询当地的数据,效率自然很高。? ·存储过程一般多由?Client?端通过存储过程的名字进行调用,即跨网传送的只是存储过程的名字及少量的参数(如果有的话),而不是构成存储过程的许多?SQL?语句,因此可以减少网络传输量,加快系统响应速度。? ·存储过程还有着如同?C?语言子函数那样的被调用和返回值的方便特性。? 所以,存储过程大大增强了?SQL?语言的功能、效率和灵活性。掌握和应用好存储过程,对进一步发挥Sybase?数据库系统的强大功能有着重要的意义。? ? 存储过程的语法规则? 建立存储过程的语法规则为: CREATE?PROCedure[owner.]procedurename[;number]? [[(]@parameter_name?datatype[=default][OUTput]? [,@parameter_name?datatype[=default][OUTput]]...[)]]? [WITH?RECOMPILE]? AS?SQL_statements? 使用存储过程的语法规则为: [EXECute][@return-status=]? [[[server.]database.]owner.]procedurename[;number]? [[@parameter_name=] value|[@parameter_name=]@varialbe[OUTput]? [,[@parameter_name=] value|[@parameter_name=]@variable[OUTput]...]]? [WITH?RECOMPILE]? [page]下面简要介绍这两个命令的常用选项以及建立和使用存储过程的要点,关于选项的更为详细的说明请参考有关手册。? ·[[[server.]database.]owner.]procedure_name:存储过程的名字。? ·@parameter_name?datatype[=default][OUTput]:形式参数(形参)的名称、类型。 dfault是赋予的缺省值(可选),OUTput指定本参数为输出参数(可选)。形参是存储过程中的自变量,可以有多个,名字必须以@打头,最长30个字符。? ·SQL_statements:定义存储过程功能的?SQL?语句。? ·@return_status:接受存储过程返回状态值的变量。? ·[@parameter_name=] value:实际参数(实参),@parameter_name?为实参的名称(可选)。如果某个实参以@parameter_name= value提供,那么随后的实参也都要采用这一形式提供。? ·[@parameter_name=]@varialbe[OUTput]:将变量?@varialbe?中的值作为实参传递给形参@parameter_name(可选),如果变量?@varialbe?是用来接受返回的参数值,则选项?OUTput?不可缺少。? ? 存储过程的建立和使用,我们将通过几个例子进行介绍。? 假设有一个用下述语句生成的技能工资表?RS-LS-GZ-JiNeng:? create?table?RS_LS_GZ_JiNeng ?/*技能工资表*/? (GeRen_id?char(4), ?/*个人代码?*/? RiQi?smalldatetime, ?/*执行日期?*/? YuanYin_id?char(1)?null, ?/*变动原因代码?*/? JinE?smallmoney) ?/*技能工资金额?*/? 该表存储着某单位员工多年来技能工资的历史档案。? 例1、如果要查询全体员工的技能工资变动历史,则可先建立一个存储过程?p-RsGz-JiNeg-All:? create?procedure?p_RsGz_JiNeng_All?as? select?*? from?RS_LS_GZ_JiNeng? order?by?GeRenid,RiQi? 然后用批处理语句调用存储过程?p_RsGz_JiNeng_All?进行查询: execute?p_RsGz_JiNeng_All? 本例只显示查询到的数据,无输入、输出参量,是最简单的一个存储过程。 例2、如果要查询某人技能工资的变动历史,可建立另一个存储过程?p_RsGz_JiNeng:? create?procedure?p_RsGz_JiNeng?@c_GeRenId?char(4)? as? select?*from?RS_LS_GZ_JiNeng? where?GeRen_id=@c_GeRenId? order?by?RiQi? 之后用批处理语句调用存储过程?p_Rs_Gz_JiNeng?进行查询:? declare?@GeRenId?char(4)? select?@GeRenId= "0135 "?/*设要查询员工的个人代码为? "0135 "?*/? execute?p_RsGz_JeNeng?@c_GeRenId=@GeRenId? 存储过程?p_RsGz_JiNeng?中定义了一个形参?@c_GeRenId,是字符型变量。在调用该过程的批处理中,既可以用具体的值也可以用变量作为实参。 用变量作实参(如本例)时,必须用?del?are?语句加以说明。值得注意的是,在批处理的调用过程语句中,@c_GeRenId=@GeRenId?中的?@?c_GeRenId?是存储过程?p_RsGz_JiNeng?中的形参名,不是批处理中的变量,所以不能将它列入?declare?语句的变量单中。? 例3/如果要计算当月工资,就必须从工资历史中查出员工距离当前最近的一次技能工资变动的结果: create?procedure?p_RsGz_JiNeng_Slt? (@c_GeRenId?char(4),@sm_JinE?smallmoney?output)? as? select?@sm_JinE=JinE? from?RS_LS_GZ_JiNeng? where?RiQi=(select?max(RiQi)? from?RS_LS_GZ_JiNeng? where?GeRenid=@c-GeRenId) /*找出历史记录中距离当前最近的日期*/? 调用存储过程?p_RsGz_JiNeng_Slt?进行查询: declare?@GeRenId?char(4),@JinE?smallmoney? select?@GeRenid= "0135 "/*设要查询员工的个人代码为? "0135 "*/? select?@JinE=0? execute?p_RsGz_JiNeng_slt?@c_GeRenId=@GeRenId,@sm_JinE=@?JinE?output? 这里,变量?@JinE?用来存储过程形参?@sm_JinE?传回的金额。在调用过程语句中,@sm_JiE?=?@JinE?output?中的?output?不可省略。否则变量?@JinE?将得不到形参传回的数值而始终为零(等于初值)。 例4、查到了个人代码为? "0135 "?员工的技能工资就显示其历史纪录,查不到则显示一条出错信息。? create?procedure?p_RsGz_JiNeng_Rtn? @c_GeRenId?char(4)? as? declare?@ErrCode?smallint? select?@ErrCode=0? if?exists(select*?from?RS-LS-GZ-JiNeng? ?where?GeRenid=@c-GeRenId)? ?begin? select?*? from?RS_LS_GZ_JiNeng? whrer?GeRen_id=@c_GeRenId? order?by?RiQi? return?@ErrCode? ?end? esle? ?begin? select?@ErrCode=1? return?@ErrCode? ?end? 调用存储过程?p_RsGz_JiNeng_Rtn:? declare?@GeRenId?char(4),@RtnCode?smallint? select?@GeRenId= "0135 "? select?@RtnCode=0? execute?@RtnCode=p_RsGz_JiNeng_Rtn?@c_GeRenId=@GeRenId? if?@RtnCode=1? ?print "No?this?one! "? 存储过程?p_RsGz_JiNeng_Rtn?向调用者返回一个存储在变量@ErrCode里的值,这个值被称为状态值,它向调用者反映存储过程执行的成败状态。在本例中,如果查不到指定员工技能工资的任何记录时,就认为 "查无此人 ",返回出错状态值?1。否则返回成功状态值?0。? 调用过程的批处理语句使用变量?@RtnCode?存储返回的状态值,一旦检出存储过程?p_RsG_?JiNeng_Rtn?返回了错误标志?(@RtnCode=1),就显示一条信息? "No?this?one! "。 小结? 上述四个例子简要介绍了存储过程常用的几种形式,从中我们已经可以领略到它的编程特色以及使用上的灵活性和方便性。? 虽然上述例子在调用存储过程时都是用?SQL?的批处理语句实现的,但并不意味着这是唯一的方法。例如在存储过程中调用存储过程(即所谓过程嵌套)的现象就很常见。另外在其它?Sybase?数据库开发系统?(如PowerBuilder)的? script?语句中调用?Sybase?的存储过程也非常普遍。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |