设有一存储过程:
CREATE PROCEDURE [dbo].[kxj_mycs]
@myabc int output
AS
BEGIN
SET NOCOUNT ON
set @myabc=1000
select a2 from csabc
RETURN 1
END
此过程含有返回值和一个记录集。
在用ASP的VBSCRIPT调用时,可以采用如下方法:
<%
Set MyComme= Server.CreateObject("ADODB.Command")
with MyComme
.ActiveConnection=conn
.CommandText="kxj_mycs" '指定存储过程名
.CommandType=4 '表明这是一个存储过程
.Prepared=true '要求将SQL命令先行编译
'返回值要最先被声明
.Parameters.Append .CreateParameter("RETURN",2,4)
'输入输出参数
.Parameters.append .CreateParameter("@myabc",3,2)
set rst=.Execute()
end with
'要获取返回值,得先关闭记录集
rst.close
myabc=MyComme(0) '返回值
myabd=MyComme(1) '输出值
'再打开记录集
rst.open
'输出记录集
if not rst.EOF then
......
%>
当然,如果可以先处理记录集,后取返回值,那就用不着将 rst 关闭后再打开了。我一直以为记录集取到客户端后,用close并不能将记录集清除掉,可有一网友经过测试坚定地认为,后面的rst.open 肯定会再次访问服务器,这下,如果数据量很大的话,那客户端与服务器端将会不必要地进行二次数据传递,这可是大大浪费资源的事情啊·!
我没有去测试,但由于我经常直接使用rst.open 命令获取记录集,因此有理由相信二次数据传递是真的,那怎么办呢?
如果采用多记录集的方式,那应该可以避免二次传递,方法如下:
在存储过程中不用 output 参数,而将原本作为 output 的参数及return返回值在程序最后用一个 select 语句组成只有一条记录的第一个记录集(前面的那条select 语句得到的是第二个记录集),即如:
CREATE PROCEDURE [dbo].[kxj_mycs]
AS
BEGIN
SET NOCOUNT ON
select a2 from csabc
select 1,1000
END
调用此存储过程时,先获取第一个记录集,即后一句 select 语句传出的参数,再转到第二个记录集获取查询结果:
<%
Set MyComme= Server.CreateObject("ADODB.Command")
with MyComme
.ActiveConnection=conn
.CommandText="kxj_mycs" '指定存储过程名
.CommandType=4 '表明这是一个存储过程
.Prepared=true '要求将SQL命令先行编译
set rst=.Execute()
end with
'获取原来设置为参数的第一个记录集的数据
myabc=rst(0)
myabd=rst(1)
'转换记录集
Set Rst = Rst.NextRecordset()
'输出记录集
if not rst.EOF then
......
%>
就可以避免对记录集先 close 而后再 open 的操作了。