然后用批处理语句调用存储过程p_RsGz_JiNeng_All进行查询:</p> execute p_RsGz_JiNeng_All
8 x% v+ ^- y3 S& u 本例只显示查询到的数据,无输入、输出参量,是最简单的一个存储过程。
: Y+ k9 ?0 s1 \& V2 C$ G( j 例2.如果要查询某人技能工资的变动历史,可建立另一个存储过程p_RsGz_JiNeng:4 C) C: L& G3 L4 m
& f; S2 p9 e* i: C' @" y$ I( H
3 s0 {& K+ n" l$ W: X5 h
create procedure p_RsGz_JiNeng @c_GeRenId char(4)
- R' x& Q, G8 u- j5 S8 w; C as * a$ E, Q5 S6 s3 t" u
select *from RS_LS_GZ_JiNeng . z) ^. N7 x- J
where GeRen_id=@c_GeRenId / U6 u2 D8 \4 [
order by RiQi; z& o f0 e l. m1 V
之后用批处理语句调用存储过程p_Rs_Gz_JiNeng进行查询:
C$ K1 I/ b6 K9 L2 l1 C declare @GeRenId char(4)! @3 G9 C7 z7 L y' c
select @GeRenId="0135" /*设要查询员工的个人代码为"0135" */% K3 I8 |' Z6 F6 j: q. P, I l9 q
execute p_RsGz_JeNeng @c_GeRenId=@GeRenId
8 z9 I9 `, m8 h 存储过程p_RsGz_JiNeng中定义了一个形参@c_GeRenId,是字符型变量。在调用该过程的批处理中,既可以用具体的值也可以用变量作为实参。用变量作实参(如本例)时,必须用del are语句加以说明。值得注意的是,在批处理的调用过程语句中,@c_GeRenId=@GeRenId中的@ c_GeRenId是存储过程p_RsGz_JiNeng中的形参名,不是批处理中的变量,所以不能将它列入d eclare语句的变量单中。
! \! ?+ H3 ^1 G 例3.如果要计算当月工资,就必须从工资历史中查出员工距离当前最近的一次技能工资变动的结果:! ?# m: [3 O. Y0 H
% `0 Z G" y0 S- q/ E. ~- M
% {6 e1 d. j8 e* T! V create procedure p_RsGz_JiNeng_Slt
5 z8 Q7 {0 Y0 d# q1 A (@c_GeRenId char(4),@sm_JinE smallmoney output)
) d4 u+ K/ C2 `; W' F4 w as
) }1 e9 _1 L- o* W7 r select @sm_JinE=JinE
e/ e- T/ c7 q9 P7 G4 w from RS_LS_GZ_JiNeng
/ R) m7 B" x* t y8 r% i% L3 t where RiQi=(select max(RiQi) 1 g2 S+ S% p% P! k& e4 q) ^
from RS_LS_GZ_JiNeng2 x& |9 n6 {( ~9 u- Y- T
where GeRenid=@c-GeRenId)/*找出历史记录中距离当前最近的日期*/
' d3 M$ w7 R0 J0 _8 u. i) B: m 调用存储过程p_RsGz_JiNeng_Slt进行查询:* O- g/ ?6 l2 ^9 R b% a
! x% i# u! Q% R7 a$ z: s
0 z7 b4 h; {5 \5 }8 `/ T declare @GeRenId char(4),@JinE smallmoney
& F$ ? v* x7 y0 m3 R0 d+ y select @GeRenid="0135"/*设要查询员工的个人代码为"0135"*/ : J: U9 m; r& T7 v; i9 K
select @JinE=0
# p% D7 _; F7 m execute p_RsGz_JiNeng_slt @c_GeRenId=@GeRenId,@sm_JinE=@ JinE output6 [1 ] e1 B# \$ D
这里,变量 @JinE用来存储过程形参@sm_JinE传回的金额。在调用过程语句中,@sm_JiE = @JinE output中的output不可省略。否则,变量@JinE将得不到形参传回的数值而始终为零(等于初值)。
# x4 z8 Y: k6 J& j/ y! S% t, Z5 k 例4.查到了个人代码为"0135"员工的技能工资就显示其历史纪录,查不到则显示一条出错信息。
% ]& t1 R2 N) }9 v9 m+ v+ h. ~
+ T, I1 b4 n- [% q6 T, r0 r% e* O: a+ }
create procedure p_RsGz_JiNeng_Rtn
9 p7 ? Y1 }- i: ^: { @c_GeRenId char(4) ; ?" R: d) G4 Y. U
as
* f! Z; s ^, ~* j" Z9 A declare @ErrCode smallint . m' |4 ^9 c3 C
select @ErrCode=0 1 [* n, r2 i( G* x# @
if exists(select* from RS-LS-GZ-JiNeng 4 k1 {2 b5 X% y c
where GeRenid=@c-GeRenId) 1 l* x! J# Z2 u" V1 j9 r& N
begin
5 h& P+ w9 g. U$ Q4 L1 D select *
3 Z. e! M4 L* b) R from RS_LS_GZ_JiNeng * t( N% J O' c5 p: l
whrer GeRen_id=@c_GeRenId 3 R( r, L" y" [
order by RiQi
0 S8 [. v" G3 w$ e2 n+ W. y return @ErrCodE ! u+ w; q2 N# `- R
end
" m0 A) |* [+ A, {5 R eslE ( U% z+ z# R, `% U) m7 r
begin " e& n N e2 U; c0 D0 H. p$ E9 Z0 w; n
select @ErrCode=1
1 c+ T" h9 s! `! ~ return @ErrCodE 6 [; b7 P9 Y: P4 |- B" H9 \5 A
end
- u% j4 L4 V& _4 l 调用存储过程p_RsGz_JiNeng_Rtn:4 A- ^* b. z5 d7 g
8 t* C7 d q+ L0 e
, r2 R. D1 A0 i( ?1 W
declare @GeRenId char(4),@RtnCode smallint
0 C3 ~0 R q, ~ S1 ~ select @GeRenId="0135"
0 U/ L! |! w! M, t ?% t. i/ J select @RtnCode=0
$ P. T. n9 c' M7 ]1 V$ B execute @RtnCode=p_RsGz_JiNeng_Rtn @c_GeRenId=@GeRenId $ H% ~; q( t! s8 B8 R
if @RtnCode=1
: I0 S- v% F5 H" B, R; u print"No this one!" `5 D P* b- V- L9 ]0 L
存储过程p_RsGz_JiNeng_Rtn向调用者返回一个存储在变量@ErrCode里的值,这个值被称为状态值,它向调用者反映存储过程执行的成败状态。在本例中,如果查不到指定员工技能工资的任何记录时,就认为"查无此人",返回出错状态值1。否则,返回成功状态值0。6 B5 u. ?8 u, K7 y! I) T
调用过程的批处理语句使用变量@RtnCode存储返回的状态值,一旦检出存储过程p_RsG_ JiNeng_Rtn返回了错误标志(@RtnCode=1),就显示一条信息"No this one!"。5 G$ G0 y$ g; a! l5 ?
小结" U, p, `8 \* }2 Q! J' n! i, n
上述四个例子简要介绍了存储过程常用的几种形式,从中我们已经可以领略到它的编程特色以及使用上的灵活性和方便性。 k8 R- }% ]! u% K" I; [
虽然上述例子在调用存储过程时都是用SQL的批处理语句实现的,但并不意味着这是唯一的方法。例如在存储过程中调用存储过程(即所谓过程嵌套)的现象就很常见。另外,在其它Sybase数据库开发系统 (如PowerBuilder)的 script语句中调用Sybase的存储过程也非常普遍。 |