
C#执行存储过程的简化-.NET教程-C#语言.docx
9页如果您需要使用本文档,请点击下载按钮下载!· C#执行存储过程的简化-.NET教程,C#语言 · 来源:作者: 发布时间:2007-12-26 10:42:08 · 域名注册o 8年专业域名注册经验 o com域名59元 虚拟主机o 提供国际CDN流量,可免备案 o 超强控制面板,可开子站点 VPS主机o 全国十余家优质机房可选 o 独立操作系统,无限开站点 下面的方法是我在实际研发中摸索出来的,能在非常大程度上简化调用存储过程的代码 首先来看一下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); mandtype = 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 ) C#调用存储过程的方法/数据库连接字符串(web.config来配置),可以动态更改connectionString支持多数据库. public static string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; ///












