资源描述
· 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;
/// <summary>
/// 执行存储过程,返回SqlDataReader ( 注意:调用该方法后,一定要对SqlDataReader进行Close )
/// </summary>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <returns>SqlDataReader</returns>
public static SqlDataReader RunProcedure(string storedProcName, IDataParameter[] parameters)
{
SqlConnection connection = new SqlConnection(connectionString);
SqlDataReader returnReader;
connection.Open();
SqlCommand command = BuildQueryCommand(connection, storedProcName, parameters);
command.CommandType = CommandType.StoredProcedure;
returnReader = command.ExecuteReader(CommandBehavior.CloseConnection);
return returnReader;
}
/// <summary>
/// 执行存储过程
/// </summary>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <param name="tableName">DataSet结果中的表名</param>
/// <returns>DataSet</returns>
public static DataSet RunProcedure(string storedProcName, IDataParameter[] parameters, string tableName)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataSet dataSet = new DataSet();
connection.Open();
SqlDataAdapter sqlDA = new SqlDataAdapter();
sqlDA.SelectCommand = BuildQueryCommand(connection, storedProcName, parameters);
sqlDA.Fill(dataSet, tableName);
connection.Close();
return dataSet;
}
}
public static DataSet RunProcedure(string storedProcName, IDataParameter[] parameters, string tableName, int Times)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataSet dataSet = new DataSet();
connection.Open();
SqlDataAdapter sqlDA = new SqlDataAdapter();
sqlDA.SelectCommand = BuildQueryCommand(connection, storedProcName, parameters);
sqlDA.SelectCommand.CommandTimeout = Times;
sqlDA.Fill(dataSet, tableName);
connection.Close();
return dataSet;
}
}
/// <summary>
/// 构建 SqlCommand 对象(用来返回一个结果集,而不是一个整数值)
/// </summary>
/// <param name="connection">数据库连接</param>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <returns>SqlCommand</returns>
private static SqlCommand BuildQueryCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters)
{
SqlCommand command = new SqlCommand(storedProcName, connection);
command.CommandType = CommandType.StoredProcedure;
foreach (SqlParameter parameter in parameters)
{
if (parameter != null)
{
// 检查未分配值的输出参数,将其分配以DBNull.Value.
if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&
(parameter.Value == null))
{
parameter.Value = DBNull.Value;
}
command.Parameters.Add(parameter);
}
}
return command;
}
/// <summary>
/// 执行存储过程,返回Output输出参数值
/// </summary>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <returns>object</returns>
public static object RunProcedure(string storedProcName, IDataParameter[] paramenters)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = BuildQueryCommand(connection, storedProcName, paramenters);
command.ExecuteNonQuery();
object obj=command.Parameters["@Output_Value"].Value; //@Output_Value和具体的存储过程参数对应
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
return null;
}
else
{
return obj;
}
}
}
/// <summary>
/// 执行存储过程,返回影响的行数
/// </summary>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <param name="rowsAffected">影响的行数</param>
/// <returns></returns>
public static int RunProcedure(string storedProcName, IDataParameter[] parameters, out int rowsAffected)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
int result;
connection.Open();
SqlCommand command = BuildIntCommand(connection, storedProcName, parameters);
rowsAffected = command.ExecuteNonQuery();
result = (int)command.Parameters["ReturnValue"].Value;
//Connection.Close();
return result;
}
}
/// <summary>
/// 创建 SqlCommand 对象实例(用来返回一个整数值)
/// </summary>
/// <param name="storedProcName">存储过程名</param>
/// <param name="parameters">存储过程参数</param>
/// <returns>SqlCommand 对象实例</returns>
private static SqlCommand BuildIntCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters)
{
SqlCommand command = BuildQueryCommand(connection, storedProcName, parameters);
command.Parameters.Add(new SqlParameter("ReturnValue",
SqlDbType.Int, 4, ParameterDirection.ReturnValue,
false, 0, 0, string.Empty, DataRowVersion.Default, null));
return command;
}
(此文档部分内容来源于网络,如有侵权请告知删除,文档可自行编辑修改内容,供参考,感谢您的配合和支持)
编辑版word
展开阅读全文