C#操作Access的一些小结
好久没有写blog,感觉今年一年都没怎么真正开心过,整天有一些事围绕在身边,使心情难以平静下来,真正写点有意义的东西。博客园是天天看的,看得多,写的少,偶尔也是Copy一篇技术文章放一下,便于自己将来查询。
最近有Winfom做了一个小系统,后台数据库是用Access,主要是单机版,考虑方便性,现在总结一些值得后来人参考的地方。
一,数据库操作基类
一般都要写个基类,这样,将来换数据库,换一下这个DA基类就行了。这个类也是从网上找的。不过感觉有的挺不错,一般就要返回dataset,datatable,datarow。还有执行sql语句,这里主要好的地方是可以带params执行,另一个就是支持事务。拿出来和大家共享一下。

代码

public static class AccessHelper
{
//数据库连接字符串
//WebForm
//public static readonly string conn_str = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + HttpContext.Current.Request.PhysicalApplicationPath + System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
//WinForm
//public static readonly string conn_str = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + AppDomain.CurrentDomain.BaseDirectory + System.Configuration.ConfigurationManager.ConnectionStrings["WZDFGL"].ConnectionString;
//public static readonly string conn_str = System.Configuration.ConfigurationManager.ConnectionStrings["WZDFGL"].ConnectionString;
public static readonly string conn_str = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + AppDomain.CurrentDomain.BaseDirectory + System.Configuration.ConfigurationManager.ConnectionStrings["WZDFGL"].ConnectionString + ";Persist Security Info=True";
// 用于缓存参数的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>
/// <remarks>
///举例:
/// int result = ExecuteNonQuery(connString, "PublishOrders", new OleDbParameter("@prodid", 24));
/// </remarks>
/// <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>
/// <remarks>
///举例:
/// int result = ExecuteNonQuery(trans, "PublishOrders", new OleDbParameter("@prodid", 24));
/// </remarks>
/// <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>
/// <remarks>
/// 举例:
/// OleDbDataReader r = ExecuteReader(connString, "PublishOrders", new OleDbParameter("@prodid", 24));
/// </remarks>
/// <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;
}
}
}
public static DataSet ExecuteDataSet(OleDbConnection conn, string cmdText, params OleDbParameter[] commandParameters)
{
//创建一个SqlCommand对象,并对其进行初始化
OleDbCommand cmd = new OleDbCommand();
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>
/// <remarks>
///例如:
/// Object obj = ExecuteScalar(connString, "PublishOrders", new OleDbParameter("@prodid", 24));
/// </remarks>
///<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>
/// <remarks>
/// 例如:
/// Object obj = ExecuteScalar(connString, "PublishOrders", new OleDbParameter("@prodid", 24));
/// </remarks>
/// <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);
}
}
}

如新增:

代码

public int InsertCby(CbyEntity objCbyEntity)
{
int intResult = 0;
string strSql = "insert into cby (dh,xm) values (@dh,@xm)";
OleDbParameter[] prams = {
new OleDbParameter("@dh", objCbyEntity.Dh),
new OleDbParameter("@xm", objCbyEntity.Xm)
};
intResult = AccessHelper.ExecuteNonQuery(AccessHelper.conn_str, strSql, prams);
return intResult;
}

用事务:

代码

public bool InsertDfdjzkOrder(DfdjzkEntity etyDfdj, DfdjhmEntity etyDfdjhm, out string errmsg)
{
bool result = true;
errmsg = "";
string strCon = AccessHelper.conn_str;
OleDbConnection con = new OleDbConnection(strCon);
try
{
con.Open();
OleDbTransaction tra = con.BeginTransaction(); //创建事务,开始执行事务
if (this.InsertDfdjzk(tra, etyDfdj) != 1)
{
tra.Rollback();
return false;
}
DfdjhmDA daDfdjhm = new DfdjhmDA();
if (daDfdjhm.UpdateDfdjhm(tra, etyDfdjhm) != 1)
{
tra.Rollback();
return false;
}
tra.Commit();//关闭事务
}
catch (Exception ex)
{
errmsg = ex.Message;
return false;
}
finally
{
con.Close();
}
return result;
}

批量更新时,一定要用同一连接,不然效率肯定狂慢。

代码

public bool UpdateXhRqBatch()
{
using (OleDbConnection conn = new OleDbConnection(AccessHelper.conn_str))
{
string strSql = "SELECT * FROM dfdjzk Where 1=1 ";//and djhm>'00050235'
DataSet ds;
ds = AccessHelper.ExecuteDataSet(conn, strSql, null);
foreach (DataRow dr in ds.Tables[0].Rows)
{
string djhm = dr[DfdjzkSchema.DJHM].ToString();
string xhrq = dr[DfdjzkSchema.XHRQ].ToString();
if (!string.IsNullOrEmpty(xhrq) && xhrq.Length == 4)
{
if (xhrq.Substring(0, 2) == "99")
{
xhrq = "19" + xhrq + "01";
}
else
{
xhrq = "20" + xhrq + "01";
}
string updatesql = "update Dfdjzk set xhrq='" + xhrq + "' where djhm ='" + djhm + "' ";
AccessHelper.ExecuteNonQuery(conn, updatesql, null);
}
}
}
return true;
}

2,一些注意点
Access对日期操作时,sql语句要用#

代码

string strSql = @"insert into Dfdjzk (zhh,yhdw,bqss1,sqss1,syl1,dj1,je1,
bqss2,sqss2,syl2,dj2,je2,
bqss3,sqss3,syl3,dj3,je3,
je,rzbz,zfbz,djhm,kprq,sssq,ssqh,xhrq,cby,sfy)
values (@zhh,@yhdw,@bqss1,@sqss1,@syl1,@dj1,@je1,
@bqss2,@sqss2,@syl2,@dj2,@je2,
@bqss3,@sqss3,@syl3,@dj3,@je3,
@je,@rzbz,@zfbz,@djhm,#" + objDfdjzkEntity.Kprq.ToString("yyyy-MM-dd") + "#,@sssq,@ssqh,@xhrq,@cby,@sfy)";

Access支持子查询,不过效率狂低,能不用最好不用,与SQL server没法比
// string strSql = @"SELECT zhh,ssqh,yhdw from yhdw where zhh<>'' and (glbz=true or
// exists (select 0 from dfdjzk where yhdw.zhh = zhh and sssq='" + sssq + @"')
// )";
用ADO.NET模糊查询时,和SQL Server一样。和直接在Access查询设计器中是不一样的概念。
if (kplq_end != "")
{
strSql += " And kprq<=#" + kplq_end + "# ";
}
if (kplq_bgn != "")
{
strSql += " And kprq>=#" + kplq_bgn + "# ";
}
if (djhm != "")
{
strSql += " And djhm like '%" + djhm + "%' ";
}
if (zhh != "")
{
strSql += " And zhh like '%" + zhh + "%' ";
}
就先写这么多吧。
C#操作Access的一些小结的更多相关文章
- C#操作access和SQL server数据库代码实例
在C#的学习中,操作数据库是比较常用的技术,而access和sql server 数据库的操作却有着不同.那么,有哪些不同呢? 首先,需要引用不同的类.因为有着不同的数据引擎. access:usin ...
- MFC通过ADO操作Access数据库
我在<VC知识库在线杂志>第十四期和第十五期上曾发表了两篇文章——“直接通过ODBC读.写Excel表格文件”和“直接通过DAO读.写Access文件”,先后给大家介绍了ODBC和DAO两 ...
- C#操作Access
C#操作Access数据库的基础知识浅析 C#操作Access数据库的基础知识都有什么呢? C#操作Access数据库的基础知识1. 通过ADO.NET的OleDb相关类来操作Access 主要知识点 ...
- Python操作Access数据库
我们在这篇文章中公分了五个步骤详细分析了Python操作Access数据库的相关方法,希望可以给又需要的朋友们带来一些帮助. AD: Python编 程语言的出现,带给开发人员非常大的好处.我们可以利 ...
- 如何通过C#操作Access,本人亲测通过
1. c# 操作access数据库 // it's your DB file path: // ApplicationEXEPath\Test.mdb var DBPath = "d:\\T ...
- 关于操作Access数据库jdk选择问题
关于操作Access数据库,使用jdk64位无法通过ODBC无法获取数据,只能通过jdk32位进行开发.
- 基于指纹考勤机的真实的PHP操作Access数据库成功案例(最终实现) 2011-11-2v
听了我的建议,我们单位的食堂准备使用一台指纹考勤机统计吃饭人次,这样院里好给食堂的承包人以相应饭补.以前买过一台彩屏指纹机,数据库是access的,今儿又买了一台准备放到食堂里,而且考虑到停电,还特地 ...
- C#操作access练习
ORM框架使用dapper,dapper不仅能操作sqlserver,也能操作access,下面为基本代码: OleDbConnection strConnection = new OleDbConn ...
- 直接通过ADO操作Access数据库
我在<VC知识库在线杂志>第十四期和第十五期上曾发表了两篇文章——“直接通过ODBC读.写Excel表格文件”和“直接通过DAO读.写Access文件”,先后给大家介绍了ODBC和DAO两 ...
随机推荐
- Asp.net Web Api进行Nunit测试
有两种方式 1.模拟Web请求. 2.直接本地调用Api接口 但是由于本地直接调用没有模拟请求环境,所以request为null public static HttpResponseMessage C ...
- [ionic开源项目教程] - 第10讲 新闻详情页的用户体验优化
目录 [ionic开源项目教程] 第1讲 前言,技术储备,环境搭建,常用命令 [ionic开源项目教程] 第2讲 新建项目,架构页面,配置app.js和controllers.js [ionic开源项 ...
- XML中对特殊字符的处置
str = str.replaceAll("‘", "‘"); str = str.replaceAll("’", "‘" ...
- asp.net webpage
一.服务器脚本基础介绍 首先,我们先复习一下Web服务器页面的基本执行方式: 1. 客户端通过在浏览器的地址栏敲入地址来发送请求到服务器端 2. 服务器接收到请求之后,发给相应的服务器端页面(也就是脚 ...
- BZOJ 2429 聪明的猴子
kruskal. #include<iostream> #include<cstdio> #include<cstring> #include<algorit ...
- ssh-keygen的用法
一.概述 1.就是为了让两个linux机器之间使用ssh不需要用户名和密码.采用了数字签名RSA或者DSA来完成这个操作 2.模型分析 假设 A (192.168.20.59)为客户机器,B(192. ...
- Js对象转String的函数 和 JSON转String
js对象转string的函数 function obj2str(o){ var r = []; if(typeof o =="string") return "" ...
- 嵌入式 hi3518平台获取网关
</pre><pre code_snippet_id="495447" snippet_file_name="blog_20141024_1_70650 ...
- C++ 虚拟继承
1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念.虚拟基类是为解决多重继承而出现的.如:类D继承自类B1.B2,而类B1.B2都继 承自类A,因此在类D中两次出现类A中的变量和函数.为了节省内 ...
- VS如何设置OpenCV静态编译
可以使用opencv提供的静态链接库也可以自己编译静态链接库. 1 使用opencv提供的静态链接库,位置如下图. 首先设置VS配置.有如下几个配置 1 工具->选项->项目和解决方案 ...