.net(C#)在Access数据库中执行sql脚本
自己写的一个工具类,主要是业务场景的需要。
主要有两个功能:
调用方式
/// <summary>
/// 执行sql语句
/// </summary>
/// <param name="sql">需要执行的sql语句</param>
public bool ExecuteSql(string sql, ref string errorMsg)
{
SetConnOpen();
string[] sqls = serializeSql(sql);
OleDbTransaction tran = conn.BeginTransaction();
try
{
comm = new OleDbCommand();
comm.Transaction = tran;
comm.Connection = conn;
foreach (string s in sqls)
{
var temps = s.Trim().Replace("\r\n", "");
if (!string.IsNullOrEmpty(temps))
{
comm.CommandText = temps;
comm.ExecuteNonQuery();
}
}
tran.Commit();
return true;
}
catch(Exception ex)
{
tran.Rollback();
errorMsg = ex.Message;
return false;
}
finally
{
conn.Close();
}
}
执行包含sql语句的字符串
/// <summary>
/// 从sql脚本文件执行
/// </summary>
/// <param name="sqlFilePath">sql脚本文件的路径</param>
/// <returns></returns>
public bool ExecuteSqlByFile(string sqlFilePath,ref string errorMsg)
{
if(!File.Exists(sqlFilePath))
{
throw new FileNotFoundException("未找到该sql脚本,请检查路径是否错误");
} string sourceSql = new StreamReader(sqlFilePath).ReadToEnd();
string[] sqls = serializeSql(sourceSql);
SetConnOpen();
OleDbTransaction tran = conn.BeginTransaction();
try
{
comm = new OleDbCommand();
comm.Transaction = tran;
comm.Connection = conn;
foreach (string s in sqls)
{
var temps = s.Trim().Replace("\r\n", "");
if (!string.IsNullOrEmpty(temps))
{
comm.CommandText = temps;
comm.ExecuteNonQuery();
}
}
tran.Commit();
return true;
}
catch (Exception ex)
{
tran.Rollback();
errorMsg = ex.Message;
return false;
}
finally
{
conn.Close();
}
}
/// <summary>
/// 将sql脚本进行序列化
/// </summary>
/// <param name="sql">sql脚本</param>
/// <returns></returns>
private string[] serializeSql(string sql)
{
string[] ss = sql.Split(new string[] { "/*go*/" }, StringSplitOptions.RemoveEmptyEntries);
return ss;
}
执行包含sql语句的文件
其实思路比较简单,就是将sql语句用字符串进行分割,然后将一条条sql语句组合成一个数组,依次进行执行即可。在执行过程中使用事务处理,当错误发生时,能够进行回滚操作。下面是完整代码:
AccessUtils.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Data.OleDb;
using System.Data.OleDb;
using System.IO;
using System.Data; namespace AccessRuntime.Bin
{
/// <summary>
/// Access工具类
/// </summary>
internal sealed class AccessUtils
{
/// <summary>
/// access数据库连接字符串
/// </summary>
private string accessConnectionString = string.Empty;
/// <summary>
/// access数据库连接对象
/// </summary>
private OleDbConnection conn;
/// <summary>
/// access数据库命令对象
/// </summary>
private OleDbCommand comm;
/// <summary>
/// access数据库连接字符串
/// </summary>
public string AccessConnectionString
{
get {
if (!string.IsNullOrEmpty(accessConnectionString))
return accessConnectionString;
else
{
string connstr = ConfigurationManager.ConnectionStrings["AccessRuntimeConnectionString"].ConnectionString;
if (string.IsNullOrEmpty(connstr))
throw new ConnectionStringElementNotFindException("未找到或未设置AccessRuntimeConnectionString节点");
else
return connstr;
}
}
}
/// <summary>
/// 初始化连接(有密码)
/// </summary>
/// <param name="filepath">可以为空,为空则调用配置文件</param>
/// <param name="pwd">数据库密码</param>
/// <example>
/// public AccessUtils("123",null)
/// </example>
public AccessUtils(string pwd,string filepath)
{
if (string.IsNullOrEmpty(filepath))
{
filepath = AccessConnectionString;
}
this.conn = new OleDbConnection(filepath + "; Jet OLEDB:Database Password=" + pwd);
conn.Open();
} /// <summary>
/// 初始化连接(无密码)
/// </summary>
/// <param name="filepath"></param>
/// <example>
/// 1.public AccessUtils(filepath)
/// 2.public AccessUtils()//不传递参数则调用配置文件
/// </example>
public AccessUtils(string filepath = null)
{
if (string.IsNullOrEmpty(filepath))
{
filepath = AccessConnectionString;
}
this.conn = new OleDbConnection(filepath);
conn.Open();
} /// <summary>
/// 执行sql语句
/// </summary>
/// <param name="sql">需要执行的sql语句</param>
public bool ExecuteSql(string sql, ref string errorMsg)
{
SetConnOpen();
string[] sqls = serializeSql(sql);
OleDbTransaction tran = conn.BeginTransaction();
try
{
comm = new OleDbCommand();
comm.Transaction = tran;
comm.Connection = conn;
foreach (string s in sqls)
{
var temps = s.Trim().Replace("\r\n", "");
if (!string.IsNullOrEmpty(temps))
{
comm.CommandText = temps;
comm.ExecuteNonQuery();
}
}
tran.Commit();
return true;
}
catch(Exception ex)
{
tran.Rollback();
errorMsg = ex.Message;
return false;
}
finally
{
conn.Close();
}
}
/// <summary>
/// 从sql脚本文件执行
/// </summary>
/// <param name="sqlFilePath">sql脚本文件的路径</param>
/// <returns></returns>
public bool ExecuteSqlByFile(string sqlFilePath,ref string errorMsg)
{
if(!File.Exists(sqlFilePath))
{
throw new FileNotFoundException("未找到该sql脚本,请检查路径是否错误");
} string sourceSql = new StreamReader(sqlFilePath).ReadToEnd();
string[] sqls = serializeSql(sourceSql);
SetConnOpen();
OleDbTransaction tran = conn.BeginTransaction();
try
{
comm = new OleDbCommand();
comm.Transaction = tran;
comm.Connection = conn;
foreach (string s in sqls)
{
var temps = s.Trim().Replace("\r\n", "");
if (!string.IsNullOrEmpty(temps))
{
comm.CommandText = temps;
comm.ExecuteNonQuery();
}
}
tran.Commit();
return true;
}
catch (Exception ex)
{
tran.Rollback();
errorMsg = ex.Message;
return false;
}
finally
{
conn.Close();
}
}
/// <summary>
/// 将sql脚本进行序列化
/// </summary>
/// <param name="sql">sql脚本</param>
/// <returns></returns>
private string[] serializeSql(string sql)
{
string[] ss = sql.Split(new string[] { "/*go*/" }, StringSplitOptions.RemoveEmptyEntries);
return ss;
}
/// <summary>
/// 获取打开的连接
/// </summary>
private void SetConnOpen()
{
if (this.conn.State != ConnectionState.Open)
{
this.conn.Open();
}
}
}
}
AccessUtils.cs
AccessTool.cs 这个是对AccessUtils类的封装,提供了更加友好的方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace AccessRuntime.Bin
{
/// <summary>
/// Access工具
/// 注意:语句之间使用 /*go*/ 进行分割
/// </summary>
public static class AccessTool
{
/// <summary>
/// 在Access数据库中执行sql语句
/// </summary>
/// <param name="sql">sql脚本</param>
/// <param name="pwd">数据库密码(如果无密码则不填写此参数)</param>
/// <returns>执行结果</returns>
public static bool ExecuteSql(string sql,string pwd = null)
{
AccessUtils au = null;
if (string.IsNullOrEmpty(pwd)) {
au = new AccessUtils();
string msg = null;
if(au.ExecuteSql(sql, ref msg))
{
return true;
}
else
{
throw new AccessRuntimeException(msg);
}
}
else
{
au = new AccessUtils(pwd, null);
string msg = null;
if(au.ExecuteSql(sql,ref msg))
{
return true;
}
else
{
throw new AccessRuntimeException(msg);
}
} } /// <summary>
/// 在Access数据库中执行sql脚本
/// </summary>
/// <param name="sqlpath">sql脚本路径</param>
/// <param name="pwd">数据库密码(如果无密码则不填写此参数)</param>
/// <returns>执行结果</returns>
public static bool ExecuteSqlByFile(string sqlpath,string pwd = null)
{
AccessUtils au = null;
//判断密码是否填写
if (string.IsNullOrEmpty(pwd))
{
au = new AccessUtils();
string msg = null;
if (au.ExecuteSqlByFile(sqlpath, ref msg))
{
return true;
}
else
{
throw new AccessRuntimeException(msg);
}
}
else
{
au = new AccessUtils(pwd, null);
string msg = null;
if (au.ExecuteSqlByFile(sqlpath, ref msg))
{
return true;
}
else
{
throw new AccessRuntimeException(msg);
}
}
} /// <summary>
/// 在指定Access数据库中执行sql语句
/// </summary>
/// <param name="sql">sql脚本</param>
/// <param name="dbpath">数据库所在路径</param>
/// <param name="pwd">执行结果</param>
/// <returns></returns>
public static bool OnExecuteSql(string sql,string dbpath,string pwd = null)
{
AccessUtils au = null;
if (string.IsNullOrEmpty(pwd))
{
au = new AccessUtils(dbpath);
string msg = null;
if (au.ExecuteSql(sql, ref msg))
{
return true;
}
else
{
throw new AccessRuntimeException(msg);
}
}
else
{
au = new AccessUtils(pwd, dbpath);
string msg = null;
if (au.ExecuteSql(sql, ref msg))
{
return true;
}
else
{
throw new AccessRuntimeException(msg);
}
} } /// <summary>
/// 在指定Access数据库中执行sql语句
/// </summary>
/// <param name="sqlpath">sql脚本路径</param>
/// <param name="dbpath">数据库所在路径</param>
/// <param name="pwd">执行结果</param>
/// <returns></returns>
public static bool OnExecuteSqlByFile(string sqlpath, string dbpath, string pwd = null)
{
AccessUtils au = null;
//判断密码是否填写
if (string.IsNullOrEmpty(pwd))
{
au = new AccessUtils(dbpath);
string msg = null;
if (au.ExecuteSqlByFile(sqlpath, ref msg))
{
return true;
}
else
{
throw new AccessRuntimeException(msg);
}
}
else
{
au = new AccessUtils(pwd, dbpath);
string msg = null;
if (au.ExecuteSqlByFile(sqlpath, ref msg))
{
return true;
}
else
{
throw new AccessRuntimeException(msg);
}
}
}
}
}
AccessToo.cs
本工具中还定义了两个自定义的异常类:AccessRuntimeException.cs,ConnectionStringElementNotFindException.cs,下付代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace AccessRuntime.Bin
{
/// <summary>
/// AccessRuntime异常
/// </summary>
public class AccessRuntimeException:Exception
{
/// <summary>
/// 配置文件节点未找到
/// </summary>
public AccessRuntimeException()
{ }
/// <summary>
/// 配置文件节点未找到
/// </summary>
/// <param name="message">异常信息</param>
public AccessRuntimeException(string message):base(message)
{ }
/// <summary>
///
/// </summary>
/// <param name="message">异常信息</param>
/// <param name="inner">异常类</param>
public AccessRuntimeException(string message, Exception inner)
: base(message, inner)
{ }
}
}
AccessRuntimeException.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace AccessRuntime.Bin
{
/// <summary>
/// 配置文件节点未找到
/// </summary>
internal class ConnectionStringElementNotFindException:Exception
{
/// <summary>
/// 配置文件节点未找到
/// </summary>
public ConnectionStringElementNotFindException()
{ }
/// <summary>
/// 配置文件节点未找到
/// </summary>
/// <param name="message">异常信息</param>
public ConnectionStringElementNotFindException(string message):base(message)
{ }
/// <summary>
///
/// </summary>
/// <param name="message">异常信息</param>
/// <param name="inner">异常类</param>
public ConnectionStringElementNotFindException(string message, Exception inner)
: base(message, inner)
{ }
}
}
ConnectionStringElementNotFindException.cs
注意:
1.使用本代码时,需要配置config文件,需要添加AccessRuntimeConnectionString的ConnectionString节点,进行Access数据库配置,当然你也可以根据自己的需要进行调整。
2.在本工具中各个sql语句间使用/*go*/进行分隔,类似mssql中的go(批处理)一样。
.net(C#)在Access数据库中执行sql脚本的更多相关文章
- InstallShield在MySQL和Oracle中执行SQL脚本的方法InstallShield在MySQL和Oracle中执行SQL脚本的方法
简述 InstallShield已经内建了对MySQL和Oracle的支持.但是这个功能是通过ODBC实现的,它对SQL脚本的格式要求非常严格,因此已经通过官方客户端测试的脚本在IS中执行时往往就会报 ...
- Eclipse中执行sql脚本文件
转自:https://blog.csdn.net/weixin_37778823/article/details/79614281 在Eclipse中导入或新建sql脚本文件(.sql文件),选择指定 ...
- navicat 中执行sql脚本 喊中文错误
执行内容和上篇一样,只是换了工具. 执行成功,但是数据库对应中文没有内容. sql脚本的编码是asci 执行的时候选择gbk 编码
- shell脚本中执行sql脚本(mysql为例)
1.sql脚本(t.sql) insert into test.t value ("LH",88); 2.shell脚本(a.sh 为方便说明,a.sh与t.sql在同一目 ...
- 2016.1.23 通过cmd在程序中执行sql脚本
System.Diagnostics.Process pro = new System.Diagnostics.Process(); pro.StartInfo.FileName = "cm ...
- shell脚本中执行sql脚本并传递参数(mysql为例)
1.mysql脚本文件 t.sql insert into test.t values(@name,@age); exit 2.shell脚本文件 a.sh (为方便演示,与t.sql文件放在同一目 ...
- mysql数据库批量执行sql文件对数据库进行操作【windows版本】
起因: 因工作需要,在本机测试环境升级mysql数据库,需逐条执行mysql数据库的sql文件对数据库进行升级,因此找了些关于mysql的文章,对批量升级数据库所需的sql文件进行升级. 整理思路: ...
- 用SQL语句创建和删除Access数据库中的表;添加列和删除列
用SQL语句创建和删除Access数据库中的表;添加列和删除列 Posted on 2009-08-11 13:42 yunbo 阅读(1240) 评论(0) 编辑 收藏 用SQL语句创建和删除Acc ...
- 在SQL Server数据库中执行存储过程很快,在c#中调用很慢的问题
记录工作中遇到的问题,分享出来: 原博客地址:https://blog.csdn.net/weixin_40782680/article/details/85038281 今天遇到一个比较郁闷的问题, ...
随机推荐
- Android View底层到底是怎么绘制的
Android绘制链图: 网上很多讲Android view的绘制流程往往只讲到了Measure - Layout - Draw. 但是,这只是一个大体的流程,而我们需要探讨的是Android在我们 ...
- Android SDK工具(谷歌提供的16个工具)简介
Android SDK包含了许多可以帮助你开发Android平台应用的工具.这些工具分为两类:一是SDK工具:而是平台工具.SDK工具独立于平台,任何开发Android应用的平台都需要配置.平台工具是 ...
- 【一天一道LeetCode】#13. Roman to Integer
一天一道LeetCode系列 (一)题目 Given a roman numeral, convert it to an integer. Input is guaranteed to be with ...
- C语言之鞍点的查找
鞍点(Saddle point)在微分方程中,沿着某一方向是稳定的,另一条方向是不稳定的奇点,叫做鞍点.在泛函中,既不是极大值点也不是极小值点的临界点,叫做鞍点.在矩阵中,一个数在所在行中是最大值,在 ...
- Gradle 1.12用户指南翻译——第三十五章. Sonar 插件
本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
- 【Android 应用开发】对Android体系结构的理解--后续会补充
1.最底层_硬件 任何Android设备最底层的硬件包括 显示屏, wifi ,存储设备 等. Android最底层的硬件会根据需要进行裁剪,选择自己需要的硬件. 2.Linux内核层 该层主要对硬件 ...
- Mac OS X 10.10优胜美地如何完美接管iphone上的电话和短信
自从今年苹果第一次的发布会上毛猫就特别注意这个功能,感觉特别Cool,特别方便.但直到今天毛猫才第一次成功测试出这个功能呀!虽然handoff功能还未测出来,但是觉得在mac上发短信和打电话也已经足够 ...
- jQuery结合lhgdialog弹出窗口,关闭时出现没有权限错误
背景: 最近的项目,使用JQuery+lhgdialog窗口组件方式模拟弹窗,在关闭lhgdialog窗口时,出现以下错误: >jQuery没有权限 >调试时 w.readyState没有 ...
- ASP.NET Provider模式应用之SqlMembershipProvider类的剖析
太多了,先给个流程图吧 Provider模式就是GOF中的两种设计模式的应用:策略模式和工厂模式,在程序中使用好这个模型能够解除模块与模块之间的耦合甚至是DIP,同时,不管是ASP.NET MVC还是 ...
- 排序算法入门之选择排序-Java实现
本文参考http://blog.csdn.net/m0_37568091/article/details/78023705 选择排序是先从对象数组中选出最小的放在第一个位置,再从剩下的元素中选择次小的 ...