.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 今天遇到一个比较郁闷的问题, ...
随机推荐
- 网站开发进阶(二十)JS中window.alert()与alert()的区别
JS中window.alert()与alert()的区别 前言 alert与window.alert没什么区别,如果有人觉得有区别,那就来解释一下:所有以window.开始的语句,都可以直接把wind ...
- RecyclerView添加Header和Footer
使用过RecyclerView的同学就知道它并没有添加header和footer的方法,而ListView和GirdView都有,但是开发过程中难免有需求需要添加一个自定义的header或者foote ...
- OPEN A PO ORDER OR SO ORDER
OPEN PO ORDER fnd_function.Execute(Function_Name => 'PO_POXPOEPO', Open_Flag => 'Y', Session_F ...
- Android UI技巧(一)——Android中伸缩自如的9patch图片切法,没有美工自给自足
Android UI技巧(一)--Android中伸缩自如的点9图片切法,没有美工自给自足 相信大家对.9 图片应该都很熟悉吧,有些人可能自己都会了,此篇献给那些不会的同学,咱们一起来聊聊.9图片的切 ...
- android应用资源预编译,编译和打包全解析
我们知道,在一个APK文件中,除了有代码文件之外,还有很多资源文件.这些资源文件是通过Android资源打包工具aapt(Android Asset Package Tool)打包到APK文件里面的. ...
- 【55】java异常机制剖析
一.为什么要使用异常 首先我们可以明确一点就是异常的处理机制可以确保我们程序的健壮性,提高系统可用率.虽然我们不是特别喜欢看到它,但是我们不能不承认它的地位,作用.有异常就说明程序存在问题,有助于我们 ...
- java的io库用到的装饰模式是如何体现的?
概论 java的io包下大概有85个类,真复杂.其实不然这些类又可以分为以下四个部分. 输入流 输出流 字节流 InputStream ...
- 拆解轮子之XRecyclerView
简介 这个轮子是对RecyclerView的封装,主要完成了下拉刷新.上拉加载更多.RecyclerView头部.在我的Material Design学习项目中使用到了项目地址,感觉还不错.趁着毕业答 ...
- OpenLayers3中wfs的属性查询
var vector = new ol.layer.Vector({ source: new ol.source.Vector({ format: new ol.format.GeoJSON(), u ...
- Java + Selenium + TestNG + Maven
环境准备: 1. Java: Install Java jdk: Version: java 1.8 or aboveConfigure Java Environment Variables:Add ...