|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
缺点:正版成本价格贵(盗版就不说了)、不够安全,大多数服务器用windows系统,没有linux安全存储历程|静态|网页 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="getUserList"指定存储历程名
.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中挪用存储历程的一些深刻的履历构成了笔墨。这个中,有些是我只知其果而不明其因的,有些多是毛病的,可是,这些都是经由我亲自理论的。列位看官批评地承受吧。有分歧定见,但愿必定向我指明,先谢了。
ASP.NET和ASP的比较,技术上比较已经没什么可说的了.新一代在大部分程度来说当然是比旧一代好了.关键看你对所做软件的理解了.因人而定.会写的话也可能比ASP.NET写得更有效率和更方便重用 |
|