机房重构——存储过程

            存储过程

      在做机房重构的时候,看好多同学都用到了存储过程,可是自己还没有用到,当时也很纳闷存储过程是什么,也不知道有什么好处和作用,只记得在学习SQL视频的时候,老师好像给讲过,但是一向有点懒的我就是不愿意找我以前的笔记,于是果断的看别人的博客,这个时候深感博客的好处。看完大神们的博客,明白了什么是存储过程,用存储过程有什么用。

一、什么是存储过程:

   存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。  ---百度百科(自我感觉解释的还是很清楚的)

二、存储过程有什么好处:

  

①重复使用。存储过程可以重复使用,从而可以减少数据库开发人员的工作量。
②减少网络流量。存储过程位于服务器上,调用的时候只需要传递存储过程的名称以及参数就可以了,因此降低了网络传输的数据量。
③安全性。参数化的存储过程可以防止SQL注入式攻击,而且可以将Grant、Deny以及Revoke权限应用于存储过程。
简单讲:
1.存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
2.当对数据库进行复杂操作时(如对多个表进行Update,Insert,Query,Delete时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。
3.存储过程可以重复使用,可减少数据库开发人员的工作量
4.安全性高,可设定只有某些用户才具有对指定存储过程的使用权
任何事物都是有两面性的,有优点必然会有缺点:
1:调试麻烦,但是用 PL/SQL Developer 调试很方便!弥补这个缺点。
2:移植问题,数据库端代码当然是与数据库相关的。但是如果是做工程型项目,基本不存在移植问题。
3:重新编译问题,因为后端代码是运行前编译的,如果带有引用关系的对象发生改变时,受影响的存储过程、包将需要重新编译(不过也可以设置成运行时刻自动编译)。
4: 如果在一个程序系统中大量的使用存储过程,到程序交付使用的时候随着用户需求的增加会导致数据结构的变化,接着就是系统的相关问题了,最后如果用户想维护该系统可以说是很难很难、而且代价是空前的,维护起来更麻烦。
当然上边的缺点都是从百度上看到的,但我自己还没有体会到缺点。。毕竟用的还少,但是优点是真的体会到了。

举例:

下边用我的机房做个例子:
在登录时会在onwork  表增加记录,同样在关闭程序的时候就要在worklog表中添加记录,同时删除onwork表中对应的记录。
UI层的代码:获得需要的信息
private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
            if ( MessageBox.Show("确定要退出系统吗?", "确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question)==DialogResult .OK )
            {    
                //删除上机表中的信息,将工作日志表中的信息补充完整。
                Login.Modle.WorkLog  offwork = new Login.Modle.WorkLog ();
                offwork.UserID = frmLogin.username;
                DateTime n=DateTime.Now;

                offwork.LogoutDate = n.ToShortDateString();
                offwork.LogoutTime = DateTime.Now.ToShortTimeString();
                offwork.Status = "false";
                LoginFacade.loginFacade facade = new LoginFacade.loginFacade();
                int table = facade.OffWorkFacade(offwork);  //传递到外观层

                Application.Exit();//  退出
            }
        }
  外观、B层、还有工厂和接口的写法,跟其他访问数据库的写法一样。
D层代码:
public int OffWork(Login.Modle.WorkLog offwork)
       {
           SqlParameter[] para ={new SqlParameter ("@userid",offwork .UserID),
                                 new SqlParameter ("@logoutdate",offwork .LogoutDate),
                                 new SqlParameter ("@logouttime",offwork .LogoutTime),
                                 new SqlParameter ("@status",offwork .Status)};
           string store = "pro_OffWork";  //此处不用写sql语句,写存储过程的名字就行
           int back = SqlHelper.DeleteSQLHelper.DelecteTable(store, para, CommandType.StoredProcedure);
           return back;
       }
  写sql语句的地方写成存储过程名字就行,另外SQLHelper中的参数类型也要写成:
CommandType.StoredProcedure
  存储过程中的代码
存储过程一般与事物一起使用,因为事务具有原子性和一致性。
ALTER PROCEDURE [dbo].[pro_OffWork]   --存储过程名字
	-- Add the parameters for the stored procedure here
	--定义下边要用到的字段。
	@userid char(10),
	@logoutdate datetime,
	@logouttime time(0),
	@status char(10)
AS
declare @logintime time(0)
BEGIN
declare @error int ---声明事物变量
set @error=0  --给事物变量赋值
BEGIN TRANSACTION --事物开始语句

select @logintime =logintime from OnWork_Info where UserID =@userid 
     --删除onwork表中相应的数据
	delete from OnWork_Info where userid=@userid

set @error =@error+@@ERROR   --事物

	--更新worklog表中相应的数据。
	update worklog_Info set LogoutDate =@logoutdate ,LogoutTime =@logouttime,status =@status where UserID =@userid and LoginTime =@logintime 

set @error =@error+@@ERROR   --事物

if @error <>0
  ROLLBACK --发生错误时回滚
else
  COMMIT  --不发生错误时执行语句

END 
   
      到这里关闭程序所需要的功能就完成了。 
   
 假如我们不用存储过程,一般的思路可能就是,先访问数据库,删除onwork表中的数据,然后再次进入数据库,在worklog表中添加记录,这样就要访问两次数据库。这样无形中会增加很多代码,但是用存储过程就只访问一次数据库就可以了,可以少写好多代码,提高我们的工作效率。
多学一些知识,多尝试着使用这些知识,你会收获很多,能提高我们的学习工作效率。



你可能感兴趣的:(机房重构——存储过程)