C#执行存储过程的简化

原创 2007年09月25日 11:43:00
下面的方法是我在实际开发中摸索出来的,可以在很大程度上简化调用存储过程的代码。

首先来看一下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, 15= '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 
)
 

C#执行存储过程的简化

下面的方法是我在实际开发中摸索出来的,可以在很大程度上简化调用存储过程的代码。首先来看一下C#调用存储过程的一般过程:1、打开数据库连接SqlConnection;2、生成一个SqlCommand;3...
  • johnsonTj
  • johnsonTj
  • 2005年02月18日 01:50
  • 719

C#完整执行存储过程的代码加实例

using System; using System.Collections.Generic; using System.Text; using System.Data.SqlClient; ...
  • tt2153
  • tt2153
  • 2016年03月20日 07:58
  • 740

c#调用存储过程执行任务超时现象

这其实算不了一篇讲技术内容的帖子,算是一个调试得冒火到最后才发现自己的一个...
  • zhongheijituan
  • zhongheijituan
  • 2014年07月01日 15:42
  • 1256

C# 执行mysql 存储过程

#region 存储过程操作 /// /// 执行存储过程,返回SqlDataReader ( 注意:调用该方法后,一定要对SqlDataReader进行Close...
  • u011470119
  • u011470119
  • 2016年05月30日 18:17
  • 3366

C#调用存储过程 返回值,输出参数,返回结果集

System.Data.SqlClient.SqlConnection sqlSvrDbCnt = new System.Data.SqlClient.SqlConnection();  //数据库连...
  • xys_777
  • xys_777
  • 2010年06月21日 17:30
  • 10507

C#开发学习笔记:C#通过存储过程创建数据表

C#开发学习笔记:C#通过存储过程创建数据表
  • JustWantToFly
  • JustWantToFly
  • 2016年09月08日 11:11
  • 761

c#调用带输出参数的存储过程

我会坚持经常就一些比较典型的问题发表博客,同学们可以长上来看看,有什么问题及时来反映。 第一篇,c#调用带输出参数的存储过程。 1.存储过程的意义 sql语句的执行大致包括,语法和语句分析,...
  • mynewdays
  • mynewdays
  • 2011年09月09日 00:16
  • 13113

C#执行SQL存储过程返回表

参考参考:/* 创建一个名为Get的储存过程先定义两个参数 ,其中@count为输出参数sql语句中 第一句返回该表所有内容, 第二句 返回表的行数,并把值赋给输出参数*/CREATE PROCEDU...
  • Rya
  • Rya
  • 2007年06月22日 12:43
  • 4188

C#中调用存储过程

1、没有参数没有返回值   2、有参数没有返回值  3、有参数有返回值     下面就这几种情况分别举例:1、没有参数没有返回值,象这种情况最简单。   存储过程   USE Nort...
  • ycl295644
  • ycl295644
  • 2015年05月05日 11:00
  • 5228

c#之执行SQL存储过程

目的:通过C#.NET调用SQL Server数据库中定义的存储过程。 示例一: 存储过程名:sp_login 输入参数1:@username nvarchar(50) 输入参数2:@pass...
  • jerry_zjnb
  • jerry_zjnb
  • 2013年06月15日 17:41
  • 3508
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C#执行存储过程的简化
举报原因:
原因补充:

(最多只允许输入30个字)