荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Peter (小飞侠), 信区: Program
标  题: Sybase存储过程的建立和使用s
发信站: BBS 荔园晨风站 (Thu Jan 21 22:43:45 1999), 转信


  存储过程的特点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[OUT
put]
    [,[@parameter_name=]value|[@parameter_name=]@variable[OU
Tput]...]]
    [WITH RECOMPILE]
    下面简要介绍这两个命令的常用选项以及建立和使用存储过程的
要点,关于选项的更为详细的说明请参考有关手册。
    ·[[[server.]database.]owner.]procedure_name:存储过程的
名字。
    ·@parameter_name datatype[=default][OUTput]:形式参数(形
参)的名称、类型。df ault是赋予的缺省值(可选),OUTput指定本参
数为输出参数(可选)。形参是存储过程中的自变量,可以有多个,名字
必须以@打头,最长30个字符。
    ·SQL_statements:定义存储过程功能的SQL语句。
    ·@return_status:接受存储过程返回状态值的变量。
    ·[@parameter_name=]value:实际参数(实参),@parameter_name
为实参的名称(可选)。如果某个实参以@parameter_name=value提供,
那么随后的实参也都要采用这一形式提供。
    ·[@parameter_name=]@varialbe[OUTput]:将变量@varialbe中
的值作为实参传递给形参@parameter_name(可选),如果变量@varialb
e是用来接受返回的参数值,则选项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中的形参名,不是批处理中的变
量,所以不能将它列入d eclare语句的变量单中。
    例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向调用者返回一个存储在变量@ErrC
ode里的值,这个值被称为状态值,它向调用者反映存储过程执行的成
败状态。在本例中,如果查不到指定员工技能工资的任何记录时,就认
为"查无此人",返回出错状态值1。否则,返回成功状态值0。
    调用过程的批处理语句使用变量@RtnCode存储返回的状态值,一
旦检出存储过程p_RsG_ JiNeng_Rtn返回了错误标志(@RtnCode=1),就
显示一条信息"No this one!"。
    小结
    上述四个例子简要介绍了存储过程常用的几种形式,从中我们已
经可以领略到它的编程特色以及使用上的灵活性和方便性。
    虽然上述例子在调用存储过程时都是用SQL的批处理语句实现的,
但并不意味着这是唯一的方法。例如在存储过程中调用存储过程(即
所谓过程嵌套)的现象就很常见。另外,在其它Sybase数据库开发系统
(如PowerBuilder)的 script语句中调用Sybase的存储过程也非常普
遍。

--
※ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: 192.168.1.3]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店