可以说存储过程这个词真的是我的一段学习经历的见证,还记得当初在学习ASP的时候, 我只会用简单的SQL语句来写程序,那个时候一边学ASP,一边给你一个不太大的公司做一个网站,公司是一个经营长江运输的物流企业,以前他们公司主页是静态的,发布新闻什么的,都很麻烦,公司没有人会做,只能把消息做成HTML挂上去,我有机会得到了这个小项目,用ASP实现新闻发布,还有人力资源交流平台的开发。可以说那个时候各个功能都实现了,但是完全没有考虑到安全性,比如最长见的SQL注入攻击,我都没有注意到,幸好是一个小的公司,没有什么太重要的信息。要不然后果可能会很严重。先来看看我那个时候是怎么写代码的吧!
strSQL = "SELECT Count(*) FROM Admin WHERE username = '"&strUserName&"' AND password = '"&strPwd&"'"
set rs = SERVER.CreateObject("ADODB.RecordSet")
rs.open conn,strSQL,1,1什么是注入攻击呢,strUserName和strPwd是从用户那里得来的输入,并没有做太多的检验,如果用户输入下面的用户名:'OR 1=1-- 这样的话,不需要用户名用密码都可以通过验证。所以,那个时候可以说真的是初涉江湖没有经验啊。
后来,从书上看到有存储过程这样的东东,很是好奇,但是并不能知道它的原理,也被它复杂的用法所困惑。直到最近开发一个实验室的管理系统时,才觉得用存储过程的好处,而在.NET中可以把数据库企业管理器做的事都搬到了VS.net 2003中了,这样既直观又方便,着实让我兴奋了一把。现在我刚刚偿到了用存储过程的甜头,下面就自己的一些体会,谈谈存储过程的好处。
存储过程是概念我不说了,哪都有。为什么用存储过程,
一:存储过程比直接在你的程序中执行单个的SQL语句更有效。
二:由于存储过程可以混合使用SQL语句和控制语句的形式书写,你可编写复杂的存储过程,它们工作起来
就像子程序一样,如同子程序,存储过程可以包含参数,这使得它们比临时构造的SQL语句更灵活。另
外NET平台还提供了,DataReader,DataSet这样的数据结构,可以很好的返回结果。
三:存储过程具有接口一致的独立性,我们可以改变存储过程的内部代码,而不用修改应用程序。
四:安全。这也是我刚开始提到的,用存储过程可以加强代码的安全性。
五:另外,存储过程配合各种控件,还可以方便的做出各种特殊的功能,下面我会举这样一个例子。
好了,说了这么多,可能有些啰嗦,但是,只有一个目的,那就是希望你爱上存储过程,并且尽可能早的使用它,而不像我,直到现在才发觉它的美!下面看一个用存储过程实现DataGrid控件分页显示的例子。
问题:大家都知道DataGrid控件提供了自动分页显示的功能,但是随着我们数据量的加大,这种分页机制的效率就打上问号了。好在,ASP.NET为我们自己定义分页提供了接口,所以我们所要做的就是:自己构造数据集。最好的方法便是存储过程。下面是做法:
1:启用定制分页:
<asp:datagrid runat="server" id="grid"
AllowPaging="true"
AllowCustomPaging="true"
OnPageIndexChange="PageIndexChanged"> 2:分页处理函数:
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
void PageIndexChanged(Object sender,DataGridPageChangedEventArgs e)
{
grid.CurrentPageIndex = e.NewPageIndex;
int n = grid.CurrentPageIndex;
grid.DataSource = CreateDataSource(n); //创建绑定数据源
grid.DataBind();
} 3:构造数据集,下面是相应的存储过程:
CREATE PROCEDURE dbo.SelectSubRecords
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//*
功能:得到各学科实验室的新闻记录
作者:石头
创建日期:2006-03-02
修改日期:2006-03-02
*/
(
@StartRow int = 0,
@StopRow int,
@type int,
@lab int
)
AS
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
declare @t_table table /**//* 构造昨时表 */
(
rownum int IDENTITY(1,1) Primary key NOT NULL,
ID int,
Type int,
Lab int,
Subject varchar(200),
Content varchar(4000),
Author varchar(20),
CreateTime datetime
)
Set RowCount @StopRow
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//*填充临时表*/
INSERT @t_table
(ID,Type,Lab,Subject,Content,Author,CreateTime)
SELECT ID,Type,Lab,Subject,Content,Author,CreateTime
FROM Artical_Info
WHERE Type=@type AND Lab=@lab
ORDER By CreateTime Desc
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//*从临时表中得到数据集*/
SELECT * FROM @t_table WHERE rownum>=@StartRow
RETURN 这样就可能按照自己的要求去实现分页显示了,而且还可以避免因为删除操作而在表中留下的ID空穴对记录显示的影响。
这个例子只是一点,我想存储过程的妙用还不至于此,对于视图也是一个很好的工具,下次有机会,我也一定总结出来。希望我的数据库知识能够不断的进步,现在正在上数据库原理,把理论与实践很好的结合,我想是我现在所要做的工作,呵呵,好了,女朋友叫我下去打羽毛球,明天她要比赛,没办法,只好当陪练了!