|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
实现规模效益。与传统的用户拥有硬件软件所有权和使用权以及传统的应用服务商提供一对一的服务模式不同,ASP拥有应用系统所有权,用户拥有使用权,应用系统集中放在ASP的数据中心中,集中管理,分散使用,以一对多的租赁的形式为众多用户提供有品质保证的应用技术服务,实现规模效益。存储历程|详解 ASP与存储历程(StoredProcedures)的文章很多,可是我嫌疑作者们是不是真正理论过。我在初学时查阅过大批相干材料,发明个中供应的良多办法实践操纵起来并非那末回事。关于复杂的使用,这些材料大概是有匡助的,但仅限于此,由于它们基本就是一模一样,相互剽窃,略微庞大点的使用,就全都语焉了。
如今,我基础上经由过程挪用存储历程会见SQLServer,以下的笔墨都是理论的总结,但愿对人人能有匡助。
存储历程就是作为可实行工具寄存在数据库中的一个或多个SQL命令。
界说老是很笼统。存储历程实在就是能完成必定操纵的一组SQL语句,只不外这组语句是放在数据库中的(这里我们只谈SQLServer)。假如我们经由过程创立存储历程和在ASP中挪用存储历程,就能够制止将SQL语句同ASP代码混同在一同。如许做的优点最少有三个:
第1、年夜年夜进步效力。存储历程自己的实行速率十分快,并且,挪用存储历程能够年夜年夜削减同数据库的交互次数。
第2、进步平安性。假设将SQL语句夹杂在ASP代码中,一旦代码掉密,同时也就意味着库布局掉密。
第3、有益于SQL语句的重用。
在ASP中,一样平常经由过程command工具挪用存储历程,依据分歧情形,本文也先容别的挪用办法。为了便利申明,依据存储历程的输出输入,作以下复杂分类:
1.只前往单一纪录集的存储历程
假定有以下存储历程(本文的目标不在于报告T-SQL语法,以是存储历程只给出代码,不作申明):
/*SP1*/
CREATEPROCEDUREdbo.getUserList
as
setnocounton
begin
select*fromdbo.[userinfo]
end
go
以上存储历程获得userinfo表中的一切纪录,前往一个纪录集。经由过程command工具挪用该存储历程的ASP代码以下:
**经由过程Command工具挪用存储历程**
DIMMyComm,MyRst
SetMyComm=Server.CreateObject("ADODB.Command")
MyComm.ActiveConnection=MyConStrMyConStr是数据库毗连字串
MyComm.CommandText="getUserList"指定存储历程名
MyComm.CommandType=4标明这是一个存储历程
MyComm.Prepared=true请求将SQL命令先行编译
SetMyRst=MyComm.Execute
SetMyComm=Nothing
存储历程获得的纪录集赋给MyRst,接上去,能够对MyRst举行操纵。
在以上代码中,CommandType属性标明哀求的范例,取值及申明以下:
-1标明CommandText参数的范例没法断定
1标明CommandText是一样平常的命令范例
2标明CommandText参数是一个存在的表称号
4标明CommandText参数是一个存储历程的称号
还能够经由过程Connection工具或Recordset工具挪用存储历程,办法分离以下:
**经由过程Connection工具挪用存储历程**
DIMMyConn,MyRst
SetMyConn=Server.CreateObject("ADODB.Connection")
MyConn.openMyConStrMyConStr是数据库毗连字串
SetMyRst=MyConn.Execute("getUserList",0,4)最初一个参断寄义同CommandType
SetMyConn=Nothing
**经由过程Recordset工具挪用存储历程**
DIMMyRst
SetMyRst=Server.CreateObject("ADODB.Recordset")
MyRst.open"getUserList",MyConStr,0,1,4
MyConStr是数据库毗连字串,最初一个参断寄义与CommandType不异
2.没有输出输入的存储历程
请看以下存储历程:
/*SP2*/
CREATEPROCEDUREdbo.delUserAll
as
setnocounton
begin
deletefromdbo.[userinfo]
end
go
该存储历程删往userinfo表中的一切纪录,没有任何输出及输入,挪用办法与下面讲过的基础不异,只是不必获得纪录集:
**经由过程Command工具挪用存储历程**
DIMMyComm
SetMyComm=Server.CreateObject("ADODB.Command")
MyComm.ActiveConnection=MyConStrMyConStr是数据库毗连字串
MyComm.CommandText="delUserAll"指定存储历程名
MyComm.CommandType=4标明这是一个存储历程
MyComm.Prepared=true请求将SQL命令先行编译
MyComm.Execute此处不用再获得纪录集
SetMyComm=Nothing
固然也可经由过程Connection工具或Recordset工具挪用此类存储历程,不外创建Recordset工具是为了获得纪录集,在没有前往纪录集的情形下,仍是使用Command工具吧。
3.有前往值的存储历程
在举行相似SP2的操纵时,应充实使用SQLServer壮大的事件处置功效,以保护数据的分歧性。而且,我们大概必要存储历程前往实行情形,为此,将SP2修正以下:
/*SP3*/
CREATEPROCEDUREdbo.delUserAll
as
setnocounton
begin
BEGINTRANSACTION
deletefromdbo.[userinfo]
IF@@error=0
begin
COMMITTRANSACTION
return1
end
ELSE
begin
ROLLBACKTRANSACTION
return0
end
return
end
go
以上存储历程,在delete顺遂实行时,前往1,不然前往0,并举行回滚操纵。为了在ASP中获得前往值,必要使用Parameters汇合来声明参数:
**挪用带有前往值的存储历程并获得前往值**
DIMMyComm,MyPara
SetMyComm=Server.CreateObject("ADODB.Command")
MyComm.ActiveConnection=MyConStrMyConStr是数据库毗连字串
MyComm.CommandText="delUserAll"指定存储历程名
MyComm.CommandType=4标明这是一个存储历程
MyComm.Prepared=true请求将SQL命令先行编译
声明前往值
SetMypara=MyComm.CreateParameter("RETURN",2,4)
MyComm.Parameters.AppendMyPara
MyComm.Execute
获得前往值
DIMretValue
retValue=MyComm(0)或retValue=MyComm.Parameters(0)
SetMyComm=Nothing
在MyComm.CreateParameter("RETURN",2,4)中,各参数的寄义以下:
第一个参数("RETURE")为参数名。参数名能够恣意设定,但一样平常应与存储过程当中声明的参数名不异。此处是前往值,我习气上设为"RETURE";
第二个参数(2),标明该参数的数据范例,详细的范例代码请参阅ADO参考,以下给出经常使用的范例代码:
adBigInt:20;
adBinary:128;
adBoolean:11;
adChar:129;
adDBTimeStamp:135;
adEmpty:0;
adInteger:3;
adSmallInt:2;
adTinyInt:16;
adVarChar:200;
关于前往值,只能取整形,且-1到-99为保存值;
第三个参数(4),标明参数的性子,此处4标明这是一个前往值。此参数取值的申明以下:
0:范例没法断定;1:输出参数;2:输出参数;3:输出或输入参数;4:前往值
以上给出的ASP代码,应当说是完全的代码,也即最庞大的代码,实在
SetMypara=MyComm.CreateParameter("RETURN",2,4)
MyComm.Parameters.AppendMyPara
能够简化为
MyComm.Parameters.AppendMyComm.CreateParameter("RETURN",2,4)
乃至还能够持续简化,稍后会做申明。
关于带参数的存储历程,只能利用Command工具挪用(也有材料说可经由过程Connection工具或Recordset工具挪用,但我没有试成过)。
4.有输出参数和输入参数的存储历程
前往值实际上是一种特别的输入参数。在年夜多半情形下,我们用到的是同时有输出及输入参数的存储历程,好比我们想获得用户信息表中,某ID用户的用户名,这时候候,有一个输出参数----用户ID,和一个输入参数----用户名。完成这一功效的存储历程以下:
/*SP4*/
CREATEPROCEDUREdbo.getUserName
@UserIDint,
@UserNamevarchar(40)output
as
setnocounton
begin
if@UserIDisnullreturn
select@UserName=username
fromdbo.[userinfo]
whereuserid=@UserID
return
end
go
挪用该存储历程的ASP代码以下:
**挪用带有输出输入参数的存储历程**
DIMMyComm,UserID,UserName
UserID=1
SetMyComm=Server.CreateObject("ADODB.Command")
MyComm.ActiveConnection=MyConStrMyConStr是数据库毗连字串
MyComm.CommandText="getUserName"指定存储历程名
MyComm.CommandType=4标明这是一个存储历程
MyComm.Prepared=true请求将SQL命令先行编译
声明参数
MyComm.Parameters.appendMyComm.CreateParameter("@UserID",3,1,4,UserID)
MyComm.Parameters.appendMyComm.CreateParameter("@UserName",200,2,40)
MyComm.Execute
获得出参
UserName=MyComm(1)
SetMyComm=Nothing
在以上代码中,能够看到,与声明前往值分歧,声明输出参数时必要5个参数,声明输入参数时必要4个参数。声明输出参数时5个参数分离为:参数名、参数数据范例、参数范例、数据长度、参数值。声明输入参数时,没有最初一个参数:参数值。
必要出格注重的是:在声明参数时,按次必定要与存储过程当中界说的按次不异,并且各参数的数据范例、长度也要与存储过程当中界说的不异。
假如存储历程有多个参数,ASP代码会显得烦琐,可使用with命令简化代码:
**挪用带有输出输入参数的存储历程(简化代码)**
DIMMyComm,UserID,UserName
UserID=1
SetMyComm=Server.CreateObject("ADODB.Command")
withMyComm
.ActiveConnection=MyConStrMyConStr是数据库毗连字串
.CommandText="getUserName"指定存储历程名
.CommandType=4标明这是一个存储历程
.Prepared=true请求将SQL命令先行编译
.Parameters.append.CreateParameter("@UserID",3,1,4,UserID)
.Parameters.append.CreateParameter("@UserName",200,2,40)
.Execute
endwith
UserName=MyComm(1)
SetMyComm=Nothing
假设我们要获得ID为1到10,10位用户的用户名,是否是要创立10次Command工具呢?不是的。假如必要屡次挪用统一存储历程,只需改动输出参数,就会失掉分歧的输入:
**屡次挪用统一存储历程**
DIMMyComm,UserID,UserName
UserName=""
SetMyComm=Server.CreateObject("ADODB.Command")
forUserID=1to10
withMyComm
.ActiveConnection=MyConStrMyConStr是数据库毗连字串
.CommandText="getUserName"指定存储历程名
.CommandType=4标明这是一个存储历程
.Prepared=true请求将SQL命令先行编译
ifUserID=1then
.Parameters.append.CreateParameter("@UserID",3,1,4,UserID)
.Parameters.append.CreateParameter("@UserName",200,2,40)
.Execute
else
从头给进参赋值(此时参数值不产生变更的进参和出参不用从头声明)
.Parameters("@UserID")=UserID
.Execute
endif
endwith
UserName=UserName+MyComm(1)+","大概你喜好用数组存储
next
SetMyComm=Nothing
经由过程以上代码能够看出:反复挪用统一存储历程时,只需为值产生改动的输出参数从头赋值便可,这一办法在有多个输出输入参数,且每次挪用时只要一个输出参数的值产生变更时,能够年夜年夜削减代码量。
5.同时具有前往值、输出参数、输入参数的存储历程
后面说过,在挪用存储历程时,声明参数的按次要与存储过程当中界说的按次不异。另有一点要出格注重:假如存储历程同时具有前往值和输出、输入参数,前往值要开始声明。
为了演示这类情形下的挪用办法,我们改良一下下面的例子。仍是获得ID为1的用户的用户名,可是有大概该用户不存在(该用户已删除,而userid是自增加的字段)。存储历程依据用户存在与否,前往分歧的值。此时,存储历程和ASP代码以下:
/*SP5*/
CREATEPROCEDUREdbo.getUserName
--为了加深对"按次"的印象,将以下两参数的界说按次倒置一下
@UserNamevarchar(40)output,
@UserIDint
as
setnocounton
begin
if@UserIDisnullreturn
select@UserName=username
fromdbo.[userinfo]
whereuserid=@UserID
if@@rowcount>0
return1
else
return0
return
end
go
**挪用同时具有前往值、输出参数、输入参数的存储历程**
DIMMyComm,UserID,UserName
UserID=1
SetMyComm=Server.CreateObject("ADODB.Command")
withMyComm
.ActiveConnection=MyConStrMyConStr是数据库毗连字串
.CommandText="getUserName"指定存储历程名
.CommandType=4标明这是一个存储历程
.Prepared=true请求将SQL命令先行编译
前往值要开始被声明
.Parameters.Append.CreateParameter("RETURN",2,4)
以下两参数的声明按次也做响应倒置
.Parameters.append.CreateParameter("@UserName",200,2,40)
.Parameters.append.CreateParameter("@UserID",3,1,4,UserID)
.Execute
endwith
ifMyComm(0)=1then
UserName=MyComm(1)
else
UserName="该用户不存在"
endif
SetMyComm=Nothing
6.同时前往参数和纪录集的存储历程
偶然候,我们必要存储历程同时前往参数和纪录集,好比在使用存储历程分页时,要同时前往纪录集和数据总量等参数。以下给出一个举行分页处置的存储历程:
/*SP6*/
CREATEPROCEDUREdbo.getUserList
@iPageCountintOUTPUT,--总页数
@iPageint,--以后页号
@iPageSizeint--每页纪录数
as
setnocounton
begin
--创立一时表
createtable#t(IDintIDENTITY,--自增字段
useridint,
usernamevarchar(40))
--向一时表中写进数据
insertinto#t
selectuserid,usernamefromdbo.[UserInfo]
orderbyuserid
--获得纪录总数
declare@iRecordCountint
set@iRecordCount=@@rowcount
--断定总页数
IF@iRecordCount%@iPageSize=0
SET@iPageCount=CEILING(@iRecordCount/@iPageSize)
ELSE
SET@iPageCount=CEILING(@iRecordCount/@iPageSize)+1
--若哀求的页号年夜于总页数,则显现最初一页
IF@iPage>@iPageCount
SELECT@iPage=@iPageCount
--断定以后页的委曲纪录
DECLARE@iStartint--startrecord
DECLARE@iEndint--endrecord
SELECT@iStart=(@iPage-1)*@iPageSize
SELECT@iEnd=@iStart+@iPageSize+1
--取以后页纪录
select*from#twhereID>@iStartandID<@iEnd
--删除一时表
DROPTABLE#t
--前往纪录总数
return@iRecordCount
end
go
在下面的存储过程当中,输出以后页号及每页纪录数,前往以后页的纪录集,总页数及纪录总数。为了更具典范性,将纪录总数以前往值的情势前往。以下是挪用该存储历程的ASP代码(详细的分页操纵略往):
**挪用分页存储历程**
DIMpagenow,pagesize,pagecount,recordcount
DIMMyComm,MyRst
pagenow=Request("pn")
自界说函数用于考证天然数
ifCheckNar(pagenow)=falsethenpagenow=1
pagesize=20
SetMyComm=Server.CreateObject("ADODB.Command")
withMyComm
.ActiveConnection=MyConStrMyConStr是数据库毗连字串
.CommandText="getUserList"指定存储历程名
.CommandType=4标明这是一个存储历程
.Prepared=true请求将SQL命令先行编译
前往值(纪录总量)
.Parameters.Append.CreateParameter("RETURN",2,4)
出参(总页数)
.Parameters.Append.CreateParameter("@iPageCount",3,2)
进参(以后页号)
.Parameters.append.CreateParameter("@iPage",3,1,4,pagenow)
进参(每页纪录数)
.Parameters.append.CreateParameter("@iPageSize",3,1,4,pagesize)
SetMyRst=.Execute
endwith
ifMyRst.state=0then未取到数据,MyRst封闭
recordcount=-1
else
MyRst.close注重:若要获得参数值,需先封闭纪录集工具
recordcount=MyComm(0)
pagecount=MyComm(1)
ifcint(pagenow)>=cint(pagecount)thenpagenow=pagecount
endif
SetMyComm=Nothing
以下显现纪录
ifrecordcount=0then
Response.Write"无纪录"
elseifrecordcount>0then
MyRst.open
dountilMyRst.EOF
......
loop
以下显现分页信息
......
elserecordcount=-1
Response.Write"参数毛病"
endif
关于以上代码,只要一点必要申明:同时前往纪录集和参数时,若要获得参数,需先将纪录集封闭,利用纪录集时再将其翻开。
7.前往多个纪录集的存储历程
本文开始先容的是前往纪录集的存储历程。偶然候,必要一个存储历程前往多个纪录集,在ASP中,怎样同时获得这些纪录集呢?为了申明这一成绩,在userinfo表中增添两个字段:usertel及usermail,并设定只要登任命户能够检察这两项内容。
/*SP7*/
CREATEPROCEDUREdbo.getUserInfo
@useridint,
@checkloginbit
as
setnocounton
begin
if@useridisnullor@checkloginisnullreturn
selectusername
fromdbo.[usrinfo]
whereuserid=@userid
--若为登任命户,取usertel及usermail
if@checklogin=1
selectusertel,usermail
fromdbo.[userinfo]
whereuserid=@userid
return
end
go
以下是ASP代码:
**挪用前往多个纪录集的存储历程**
DIMchecklg,UserID,UserName,UserTel,UserMail
DIMMyComm,MyRst
UserID=1
checklogin()为自界说函数,判别会见者是不是登录
checklg=checklogin()
SetMyComm=Server.CreateObject("ADODB.Command")
withMyComm
.ActiveConnection=MyConStrMyConStr是数据库毗连字串
.CommandText="getUserInfo"指定存储历程名
.CommandType=4标明这是一个存储历程
.Prepared=true请求将SQL命令先行编译
.Parameters.append.CreateParameter("@userid",3,1,4,UserID)
.Parameters.append.CreateParameter("@checklogin",11,1,1,checklg)
SetMyRst=.Execute
endwith
SetMyComm=Nothing
从第一个纪录会合取值
UserName=MyRst(0)
从第二个纪录会合取值
ifnotMyRstisNothingthen
SetMyRst=MyRst.NextRecordset()
UserTel=MyRst(0)
UserMail=MyRst(1)
endif
SetMyRst=Nothing
以上代码中,使用Recordset工具的NextRecordset办法,获得了存储历程前往的多个纪录集。
至此,针对ASP挪用存储历程的各类情形,本文已做了较为周全的申明。最初说一下在一个ASP程序中,挪用多个存储历程的分歧办法。
在一个ASP程序中,挪用多个存储历程最少有以下三种办法是可行的:
1.创立多个Command工具
DIMMyComm
SetMyComm=Server.CreateObject("ADODB.Command")
挪用存储历程一
......
SetMyComm=Nothing
SetMyComm=Server.CreateObject("ADODB.Command")
挪用存储历程二
......
SetMyComm=Nothing
......
2.只创立一个Command工具,停止一次挪用时,扫除其参数
DIMMyComm
SetMyComm=Server.CreateObject("ADODB.Command")
挪用存储历程一
.....
扫除参数(假定有三个参数)
MyComm.Parameters.delete2
MyComm.Parameters.delete1
MyComm.Parameters.delete0
挪用存储历程二并扫除参数
......
SetMyComm=Nothing
此时要注重:扫除参数的按次与参数声明的按次相反,缘故原由嘛,我也不晓得。
3.使用Parameters数据汇合的Refresh办法重置Parameter工具
DIMMyComm
SetMyComm=Server.CreateObject("ADODB.Command")
挪用存储历程一
.....
重置Parameters数据汇合中包括的一切Parameter工具
MyComm.Parameters.Refresh
挪用存储历程二
.....
SetMyComm=Nothing
一样平常以为,反复创立工具是效力较低的一种办法,可是经测试(测试工具为MicrosoftApplicationCenterTest),了局出人意表:
办法2>=办法1>>办法3
办法2的运转速率年夜于即是办法1(最多可高4%摆布),这两种办法的运转速率宏大于办法3(最多竟高达130%),以是倡议在参数多时,接纳办法1,在参数较少时,接纳办法2。
花了一天的工夫,终究把我关于在ASP中挪用存储历程的一些深刻的履历构成了笔墨。这个中,有些是我只知其果而不明其因的,有些多是毛病的,可是,这些都是经由我亲自理论的。列位看官批评地承受吧。有分歧定见,但愿必定向我指明,先谢了。Access是一种桌面数据库,只适合数据量少的应用,在处理少量数据和单机访问的数据库时是很好的,效率也很高。但是它的同时访问客户端不能多于4个。access数据库有一定的极限,如果数据达到100M左右,很容易造成服务器iis假死,或者消耗掉服务器的内存导致服务器崩溃。 |
|