网站经常出现未知错误,隔一段时间自己又好了,后来发现是数据连接没有及时关闭释放,我基础很差,对数据库连接方面不懂,所以用微软的AccessHelper数据操作类,使用方法如下,哪位朋友能帮忙看一下数据连接为什么会没有及时关闭释放,要怎么改?
之前有问一位朋友,说是把string con = AccessHelper.conn;改成string con="Provider=Microsoft.Jet.OLEDB.4.0;......db.mdb";或者用using(string con = AccessHelper.conn){}
我用第一种方法是可以,但这种却要把数据库连接地址写在这,很不方便,第二种说要用using则accesshelper必需继承IDdispose...的接口,但accesshelper是静态,不能继承,不知道怎么改.
哪位朋友有时间帮忙看一下,需要怎么改,最好能稍解释一下.谢谢了.
顺便帮我看一下,我这样操作数据有什么不好的,该怎么优化?
如果解释得比较详细,俺可以再加些分.
如果看这样看代码太麻烦也可看图片:http://www.phhui.com/pic.jpgusing System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;/// <summary>
///sqltext 的摘要说明
/// </summary>
public class sqltext
{
public sqltext()
{
//
//TODO: 在此处添加构造函数逻辑
//
}
public DataTable db_SelectTable(string img,string[] val)
{
string sql;
string con = AccessHelper.conn;
stringreplace str = new stringreplace();//特殊字符过滤
switch (img)
{
case "db_votes": sql = "select * from db_Votes order by id asc"; break;
case "db_votesdate": sql = "select db_Votesdate from db_User where db_Useremail='" + str.resetstring(val[0]) + "'"; break;
case "db_contestants": sql = "select * from db_Votes where id=" + str.resetstring(val[0]); break;
default: sql = null; break;
}
return AccessHelper.ExecuteDataSet(con, sql).Tables[0];
}
public Boolean updatedate(string img, string[] val)
{
string sql;
string con = AccessHelper.conn;
stringreplace str = new stringreplace();
md6 mymd5 = new md6();
switch (img)
{
case "db_activate": sql = "update db_User set db_Authcode='Already activated',db_Act_date='"+DateTime.Now.ToString()+"',db_Act_ip='"+val[1]+"' where db_Authcode='" + str.resetstring(val[0]) + "'"; break;
case "db_votes": sql = "update db_Votes set db_Votes='"+val[1]+"' where id=" + val[0]; break;
case "db_votesdate": sql = "update db_User set db_Votesdate='" + str.resetstring(val[0]) + "',db_Target_date=db_Target_date+'" + str.resetstring(val[2]) + "at " + DateTime.Now.ToString() + "/" + "' where db_Useremail='" + str.resetstring(val[1]) + "'"; break;
case "db_setcode": sql = "update db_User set db_Resetpwd='" + str.resetstring(val[1]) + "' where db_Useremail='" + str.resetstring(val[0]) + "'"; break;
case "db_resetpwd": sql = "update db_User set db_Userpassword='" + mymd5.mymd6(val[1]) + "',db_Resetpwd='null' where db_Resetpwd='" + str.resetstring(val[0]) + "'"; break;
default: sql = null; break;
}
if (AccessHelper.ExecuteNonQuery(con, sql) != -1)
{
return true;
}
else
{
return false;
}
}
}
之前有问一位朋友,说是把string con = AccessHelper.conn;改成string con="Provider=Microsoft.Jet.OLEDB.4.0;......db.mdb";或者用using(string con = AccessHelper.conn){}
我用第一种方法是可以,但这种却要把数据库连接地址写在这,很不方便,第二种说要用using则accesshelper必需继承IDdispose...的接口,但accesshelper是静态,不能继承,不知道怎么改.
哪位朋友有时间帮忙看一下,需要怎么改,最好能稍解释一下.谢谢了.
顺便帮我看一下,我这样操作数据有什么不好的,该怎么优化?
如果解释得比较详细,俺可以再加些分.
如果看这样看代码太麻烦也可看图片:http://www.phhui.com/pic.jpgusing System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;/// <summary>
///sqltext 的摘要说明
/// </summary>
public class sqltext
{
public sqltext()
{
//
//TODO: 在此处添加构造函数逻辑
//
}
public DataTable db_SelectTable(string img,string[] val)
{
string sql;
string con = AccessHelper.conn;
stringreplace str = new stringreplace();//特殊字符过滤
switch (img)
{
case "db_votes": sql = "select * from db_Votes order by id asc"; break;
case "db_votesdate": sql = "select db_Votesdate from db_User where db_Useremail='" + str.resetstring(val[0]) + "'"; break;
case "db_contestants": sql = "select * from db_Votes where id=" + str.resetstring(val[0]); break;
default: sql = null; break;
}
return AccessHelper.ExecuteDataSet(con, sql).Tables[0];
}
public Boolean updatedate(string img, string[] val)
{
string sql;
string con = AccessHelper.conn;
stringreplace str = new stringreplace();
md6 mymd5 = new md6();
switch (img)
{
case "db_activate": sql = "update db_User set db_Authcode='Already activated',db_Act_date='"+DateTime.Now.ToString()+"',db_Act_ip='"+val[1]+"' where db_Authcode='" + str.resetstring(val[0]) + "'"; break;
case "db_votes": sql = "update db_Votes set db_Votes='"+val[1]+"' where id=" + val[0]; break;
case "db_votesdate": sql = "update db_User set db_Votesdate='" + str.resetstring(val[0]) + "',db_Target_date=db_Target_date+'" + str.resetstring(val[2]) + "at " + DateTime.Now.ToString() + "/" + "' where db_Useremail='" + str.resetstring(val[1]) + "'"; break;
case "db_setcode": sql = "update db_User set db_Resetpwd='" + str.resetstring(val[1]) + "' where db_Useremail='" + str.resetstring(val[0]) + "'"; break;
case "db_resetpwd": sql = "update db_User set db_Userpassword='" + mymd5.mymd6(val[1]) + "',db_Resetpwd='null' where db_Resetpwd='" + str.resetstring(val[0]) + "'"; break;
default: sql = null; break;
}
if (AccessHelper.ExecuteNonQuery(con, sql) != -1)
{
return true;
}
else
{
return false;
}
}
}
我用的AccessHelper.cs http://www.phhui.com/AccessHelper.cs
你把要执行SQL的语句放入try{}在finally里关闭数据连接。close和dispose的.
关闭和释放资源
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.OleDb;
using System.Collections;/// <summary>
/// AcceHelper 的摘要说明
/// </summary>
public static class AccessHelper
{
//数据库连接字符串
public static readonly string conn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ApplicationPath + "/access/") + "JASMINE.mdb";
// 用于缓存参数的HASH表
private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable());
/// <summary>
/// 给定连接的数据库用假设参数执行一个sql命令(不返回数据集)
/// </summary>
/// <param name="connectionString">一个有效的连接字符串</param>
/// <param name="commandText">存储过程名称或者sql命令语句</param>
/// <param name="commandParameters">执行命令所用参数的集合</param>
/// <returns>执行命令所影响的行数</returns>
public static int ExecuteNonQuery(string connectionString, string cmdText, params OleDbParameter[] commandParameters)
{
OleDbCommand cmd = new OleDbCommand();
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
PrepareCommand(cmd, conn, null, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}
}
/// <summary>
/// 用现有的数据库连接执行一个sql命令(不返回数据集)
/// </summary>
/// <res>
///举例:
/// int result = ExecuteNonQuery(connString, "PublishOrders", new OleDbParameter("@prodid", 24));
/// </res>
/// <param name="conn">一个现有的数据库连接</param>
/// <param name="commandText">存储过程名称或者sql命令语句</param>
/// <param name="commandParameters">执行命令所用参数的集合</param>
/// <returns>执行命令所影响的行数</returns>
public static int ExecuteNonQuery(OleDbConnection connection, string cmdText, params OleDbParameter[] commandParameters)
{
OleDbCommand cmd = new OleDbCommand();
PrepareCommand(cmd, connection, null, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}
/// <summary>
///使用现有的SQL事务执行一个sql命令(不返回数据集)
/// </summary>
/// <res>
///举例:
/// int result = ExecuteNonQuery(trans, "PublishOrders", new OleDbParameter("@prodid", 24));
/// </res>
/// <param name="trans">一个现有的事务</param>
/// <param name="commandText">存储过程名称或者sql命令语句</param>
/// <param name="commandParameters">执行命令所用参数的集合</param>
/// <returns>执行命令所影响的行数</returns>
public static int ExecuteNonQuery(OleDbTransaction trans, string cmdText, params OleDbParameter[] commandParameters)
{
OleDbCommand cmd = new OleDbCommand();
PrepareCommand(cmd, trans.Connection, trans, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}
/// <summary>
/// 用执行的数据库连接执行一个返回数据集的sql命令
/// </summary>
/// <res>
/// 举例:
/// OleDbDataReader r = ExecuteReader(connString, "PublishOrders", new OleDbParameter("@prodid", 24));
/// </res>
/// <param name="connectionString">一个有效的连接字符串</param>
/// <param name="commandText">存储过程名称或者sql命令语句</param>
/// <param name="commandParameters">执行命令所用参数的集合</param>
/// <returns>包含结果的读取器</returns>
public static OleDbDataReader ExecuteReader(string connectionString, string cmdText, params OleDbParameter[] commandParameters)
{
//创建一个SqlCommand对象
OleDbCommand cmd = new OleDbCommand();
//创建一个SqlConnection对象
OleDbConnection conn = new OleDbConnection(connectionString);
//在这里我们用一个try/catch结构执行sql文本命令/存储过程,因为如果这个方法产生一个异常我们要关闭连接,因为没有读取器存在,
//因此commandBehaviour.CloseConnection 就不会执行
try
{
//调用 PrepareCommand 方法,对 SqlCommand 对象设置参数
PrepareCommand(cmd, conn, null, cmdText, commandParameters);
//调用 SqlCommand 的 ExecuteReader 方法
OleDbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
//清除参数
cmd.Parameters.Clear();
return reader;
}
catch
{
//关闭连接,抛出异常
conn.Close();
throw;
}
}
/// <summary>
/// 返回一个DataSet数据集
/// </summary>
/// <param name="connectionString">一个有效的连接字符串</param>
/// <param name="cmdText">存储过程名称或者sql命令语句</param>
/// <param name="commandParameters">执行命令所用参数的集合</param>
/// <returns>包含结果的数据集</returns>
public static DataSet ExecuteDataSet(string connectionString, string cmdText, params OleDbParameter[] commandParameters)
{
//创建一个SqlCommand对象,并对其进行初始化
OleDbCommand cmd = new OleDbCommand();
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
PrepareCommand(cmd, conn, null, cmdText, commandParameters);
//创建SqlDataAdapter对象以及DataSet
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
try
{
//填充ds
da.Fill(ds);
// 清除cmd的参数集合
cmd.Parameters.Clear();
//返回ds
return ds;
}
catch
{
//关闭连接,抛出异常
conn.Close();
throw;
}
}
}
/// <summary>
/// 用指定的数据库连接字符串执行一个命令并返回一个数据集的第一列
/// </summary>
/// <res>
///例如:
/// Object obj = ExecuteScalar(connString, "PublishOrders", new OleDbParameter("@prodid", 24));
/// </res>
///<param name="connectionString">一个有效的连接字符串</param>
/// <param name="commandText">存储过程名称或者sql命令语句</param>
/// <param name="commandParameters">执行命令所用参数的集合</param>
/// <returns>用 Convert.To{Type}把类型转换为想要的 </returns>
public static object ExecuteScalar(string connectionString, string cmdText, params OleDbParameter[] commandParameters)
{
OleDbCommand cmd = new OleDbCommand();
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
PrepareCommand(cmd, connection, null, cmdText, commandParameters);
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
return val;
}
}
/// <summary>
/// 用指定的数据库连接执行一个命令并返回一个数据集的第一列
/// </summary>
/// <res>
/// 例如:
/// Object obj = ExecuteScalar(connString, "PublishOrders", new OleDbParameter("@prodid", 24));
/// </res>
/// <param name="conn">一个存在的数据库连接</param>
/// <param name="commandText">存储过程名称或者sql命令语句</param>
/// <param name="commandParameters">执行命令所用参数的集合</param>
/// <returns>用 Convert.To{Type}把类型转换为想要的 </returns>
public static object ExecuteScalar(OleDbConnection connection, string cmdText, params OleDbParameter[] commandParameters)
{
OleDbCommand cmd = new OleDbCommand();
PrepareCommand(cmd, connection, null, cmdText, commandParameters);
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
return val;
}
/// <summary>
/// 将参数集合添加到缓存
/// </summary>
/// <param name="cacheKey">添加到缓存的变量</param>
/// <param name="cmdParms">一个将要添加到缓存的sql参数集合</param>
public static void CacheParameters(string cacheKey, params OleDbParameter[] commandParameters)
{
parmCache[cacheKey] = commandParameters;
}
/// <summary>
/// 找回缓存参数集合
/// </summary>
/// <param name="cacheKey">用于找回参数的关键字</param>
/// <returns>缓存的参数集合</returns>
public static OleDbParameter[] GetCachedParameters(string cacheKey)
{
OleDbParameter[] cachedParms = (OleDbParameter[])parmCache[cacheKey];
if (cachedParms == null)
return null;
OleDbParameter[] clonedParms = new OleDbParameter[cachedParms.Length];
for (int i = 0, j = cachedParms.Length; i < j; i++)
clonedParms = (OleDbParameter[])((ICloneable)cachedParms).Clone();
return clonedParms;
}
/// <summary>
/// 准备执行一个命令
/// </summary>
/// <param name="cmd">sql命令</param>
/// <param name="conn">Sql连接</param>
/// <param name="trans">Sql事务</param>
/// <param name="cmdText">命令文本,例如:Select * from Products</param>
/// <param name="cmdParms">执行命令的参数</param>
private static void PrepareCommand(OleDbCommand cmd, OleDbConnection conn, OleDbTransaction trans, string cmdText, OleDbParameter[] cmdParms)
{
//判断连接的状态。如果是关闭状态,则打开
if (conn.State != ConnectionState.Open)
conn.Open();
//cmd属性赋值
cmd.Connection = conn;
cmd.CommandText = cmdText;
//是否需要用到事务处理
if (trans != null)
cmd.Transaction = trans;
cmd.CommandType = CommandType.Text;
//添加cmd需要的存储过程参数
if (cmdParms != null)
{
foreach (OleDbParameter parm in cmdParms)
cmd.Parameters.Add(parm);
}
}
//自定义方法
}
{
OleDbCommand cmd = new OleDbCommand();
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
PrepareCommand(cmd, conn, null, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}
}
多用using
http://topic.csdn.net/u/20090304/14/a45a0b3f-efb6-4cbc-b40a-16701bf0c1d7.html
补充一点:尽量少用字符串拼接SQL语句,这样做不安全,多用参数的形式!
public static OleDbDataReader ExecuteReader(string connectionString, string cmdText, params OleDbParameter[] commandParameters)
{
//...
}可能是
OleDbDataReader dr = AccessHelper.ExecuteReader(...);
//使用dr
dr.Close(); //关闭DataReader时同时关闭数据库连接Access数据库由于并发性不好,尤其要注意数据库连接的关闭
UP,很多时候的确由此引起,建议你使用DataReader的地方用using{}括起来
using(OleDbDataReader dr = AccessHelper.ExecuteReader(...))
{
。
}
http://rimland.blog.163.com/blog/static/8832546200981835850969/