C#执行存储过程的简化

下面的方法是我在实际开发中摸索出来的,可以在很大程度上简化调用存储过程的代码。

首先来看一下C#调用存储过程的一般过程:
1、打开数据库连接SqlConnection;
2、生成一个SqlCommand;
3、向命令对象填充参数;
4、执行存储过程;
5、关闭连接;
6、其他操作。

我这里讲的主要是简化第3步操作,最终在调用存储过程的时候只需要传递存储过程的名字和相应的参数值。调用示例如下:
dbAccess.run("p_am_deleteFile", new object[]{LoginId, Request.UserHostAddress, fileId});

由于在填充参数的时候必须要两个值,一个是参数的名字,一个是参数的值。参数值是由外部传入的,不用考虑;而参数名称是和存储过程相关的东西,应该可以由存储过程名称来确定而不用每次调用的时候写上一遍。对于这个问题,如果能将存储过程的参数保存到一个全局的地方,那么在调用存储过程的时候只要能根据存储过程的名字去索引就可以了。具体实现的时候我是将这些信息保存在数据库访问组件里面,采用名字/值对的方式。代码如下: 
public   class  InfoTable : NameObjectCollectionBase 

public object this[string key] 

get 

return(this.BaseGet(key)); 
}
 
set 

this.BaseSet(key, value); 
}
 
}
 
}
 
。。。。。。 
protected   static  InfoTable procInfoTable  =   new  InfoTable(); 
。。。。。。 
public   static  InfoTable ProcInfoTable 

get 

return procInfoTable; 
}
 
}


这样的话,在实际调用存储过程的时候就只需要去查这张表就可以知道存储过程的参数名了。实现代码如下: 
public  DataTable run( string  procName,  object [] parms,  ref   int  retValue) 

string[] paramInfo = (string[])(procInfoTable[procName]); 
if (paramInfo == null

ErrorInfo.setErrorInfo(
"未取得" + procName + "的参数!"); 
return null
}
 

bool bOpened = (dbConn.State == ConnectionState.Open); 
if (!bOpened && !connect()) 

return null
}
 

DataSet ds 
= new DataSet(); 
try 

SqlCommand cmd 
= new SqlCommand(procName, dbConn); 
cmd.CommandType 
= CommandType.StoredProcedure; 

for (int i = 0; i < parms.Length && i < paramInfo.Length; ++i) 

cmd.Parameters.Add(
new SqlParameter(paramInfo[i], parms[i])); 
}
 

SqlParameter parmsr 
= new SqlParameter("return", SqlDbType.Int); 
parmsr.Direction 
= ParameterDirection.ReturnValue; 
cmd.Parameters.Add(parmsr); 

SqlDataAdapter adp 
= new SqlDataAdapter(cmd); 
adp.Fill(ds); 
retValue 
= (int)(cmd.Parameters["return"].Value); 
}
 
catch (Exception ex) 

ErrorInfo.setErrorInfo(ex.Message); 

retValue 
= -1
}
 

if (!bOpened) 
close(); 

if (ds.Tables.Count > 0
return ds.Tables[0]; 
else 
return null
}


可以看出,每个存储过程的参数列表存储为了一个string[]。接下来的工作就是将系统里头许许多多的存储过程的参数填充到表ProcInfoTable中。我所用的数据库是Sql Server 2000,下面给出一个存储过程来解决这个烦人的问题:
create   PROCEDURE  dbo.p_am_procInfo 

@procName  t_str64  -- 存储过程的名字 

AS  
begin  
set  nocount  on  

if   @procName   =   ''   begin  
select  name  as  procName 
from  sysobjects 
where   substring (sysobjects.name,  1 5 =   ' p_am_ '  
end  
else   begin  
select  
syscolumns.name 
as  paramName 
from  sysobjects, syscolumns 
where  sysobjects.id  =  syscolumns.id 
and  sysobjects.name  =   @procName  
order   by  colid 
end  

end  


这个存储过程有两个作用,在没有传递存储过程的名字的时候,该存储过程返回所有以”p_am_”开头的存储过程的名字;在传入了相应的存储过程名字后,该存储过程返回该存储过程的参数列表。这样一来,我们在程序开始的地方就可以将系统里的存储过程参数列表取出来并保存到数据库访问组件的ProcInfoTable属性中了。具体代码如下: 
span.DBAccess dbAccess  =   new  span.DBAccess(); 

//  
// 构造取存储过程的参数表 
//  
span.DBAccess.ProcInfoTable[ " p_am_procInfo " =   new   string [] {"@procName"}

//  
// 取得其他存储过程列表 
//  
DataTable dt  =  dbAccess.run( " p_am_procInfo " new   object [] {""} ); 
if  (dt  ==   null   ||  dt.Rows.Count  <=   0

return
}
 

//  
// 取得其他存储过程的参数表 
//  
foreach  (DataRow dr  in  dt.Rows) 

DataTable dtParams 
= dbAccess.run("p_am_procInfo"new object[]{dr["procName"]}); 
if (dtParams != null

string[] paramInfo = new string[dtParams.Rows.Count]; 
for (int i = 0; i < dtParams.Rows.Count; ++i) 
paramInfo[i] 
= dtParams.Rows[i]["paramName"].ToString(); 

span.DBAccess.ProcInfoTable[dr[
"procName"].ToString()] = paramInfo; 
}
 
}


至此,全部技术细节介绍完毕。另外,数据库访问对象的几个接口函数也一并给出: 

// 打开、关闭数据库连接 
public   bool  connect( string  strConn) 
public   bool  connect() 
public   bool  close() 

// 执行SQL命令(只有一个int返回) 
public   int  exec( string  procName,  object [] parms) 
public   int  exec( string  sql) 

// 运行(返回一个DataTable) 
public  DataTable run( string  procName,  object [] parms,  ref   int  retValue) 
public  DataTable run( string  procName,  object [] parms) 
public  DataTable run( string  sql) 

// 分页查询(页号从1开始,返回一个DataTable) 
public  DataTable pageQuery 

string  selectCmd, 
int  pageSize, 
int  pageNumber 
)
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值