前言:
一直没用机会用C#操作ODBC,因为主流数据库有专用的ADO.NET,比如
using System.Data.SqlClient;
using MySql.Data.MySqlClient;
using System.Data.OleDb;
SqlConnection conn = new SqlConnection(ConnectString);
MySqlConnection conn = new MySqlConnection(ConnectString);
OleDbConnection conn = new OleDbConnection(ConnectString);
对于非主流数据库,微软的可以使用OleDb,其他的可能就只能使用ODBC了。
今天这篇博客的引子是传奇数据库,网上资料比较少,本人也是第一次使用ODBC特此记录。
正文:
1、C#通过ODBC连接DBC数据库
1.1、安装完DBC2000,我们一般会看到这个画面
注意看我圈起来得关键字,这个是数据库的类型,也就是我们常说的传奇DBC数据库实际上是Paradox数据库
1.2、接下来的第一反应就是要看看ODBC管理器里面有没有这个数据库驱动
这个是控制面板的ODBC管理器,里面是没有Paradox驱动的,幸好本人喜欢乱点,带驱动的管理器入口在这里↓
1.3、接下来我们就建立个ODBC数据源,随便起个名吧 Paradox-HeroDb,配置如下,重点已划出
1.4、数据源建好了,查MSDN文档,看看ODBC怎么玩
1.4.1、VS的可视化ODBC数据源
1.4.2、脱离管理器的连接字符串
@"Driver={Microsoft Paradox Driver (*.db )};DBQ=D:\MirDB;"
这个驱动名在这里找↓
1.4.3、基于管理器的连接字符串,特别注意,两种连接字符串内部不可出现''和"",出现这两种字符会出现各种奇怪报错,而且用百度搜索是找不到原因滴。。。出现空格没问题
"Dsn=Paradox-HeroDb;"
1.5、上代码:
using System;
namespace CommonUtils.Test
{
class Program
{
static void Main(string[] args)
{
DbOdbc odbc1 = new DbOdbc(@"Driver={Microsoft Paradox Driver (*.db )};DBQ=D:\MirDB;");
Console.WriteLine(odbc1.GetTableNames().ToJson());
DbOdbc odbc2 = new DbOdbc("Dsn=Paradox-HeroDb;");
Console.WriteLine(odbc2.GetTableNames().ToJson());
Console.ReadKey();
}
}
}
代码里面的ToJson我就不上传了,是NewtonSoft对object的扩展,DbOdbc↓
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.Odbc;
namespace CommonUtils
{
/// <summary>
/// Odbc数据库
/// </summary>
public class DbOdbc
{
/// <summary>
/// 连接字符串
/// </summary>
public string ConnectString { get; private set; }
/// <summary>
/// 初始化
/// </summary>
public DbOdbc(string connString)
{
ConnectString = connString;
}
/// <summary>
/// 是否可连接
/// </summary>
public bool CanConnect()
{
OdbcConnection conn = new OdbcConnection(ConnectString);
try
{
conn.Open();
conn.Close();
ConnectInfo = StringUtil.Success;
return true;
}
catch (Exception ex)
{
ConnectInfo = ex.Message;
return false;
}
finally
{
conn.Dispose();
}
}
/// <summary>
/// 连接信息
/// </summary>
public string ConnectInfo { get; private set; }
/// <summary>
/// 获取DataReader
/// </summary>
public DbDataReader GetDataReader(string sql, Dictionary<string, object> map = null)
{
OdbcConnection conn = new OdbcConnection(ConnectString);
conn.Open();
OdbcCommand cmd = new OdbcCommand(sql, conn);
AddParameters(cmd, map);
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
/// <summary>
/// 获取DataTable
/// </summary>
public DataTable GetDataTable(string sql, Dictionary<string, object> map = null)
{
OdbcConnection conn = new OdbcConnection(ConnectString);
conn.Open();
OdbcCommand cmd = new OdbcCommand(sql, conn);
AddParameters(cmd, map);
OdbcDataAdapter da = new OdbcDataAdapter(cmd);
DataTable table = new DataTable();
da.Fill(table);
cmd.Dispose();
conn.Close();
conn.Dispose();
return table;
}
/// <summary>
/// 获取DataRow
/// </summary>
public DataRow GetDataRow(string sql, Dictionary<string, object> map = null)
{
DataTable table = GetDataTable(sql, map);
if (table.Rows.Count > 0)
return table.Rows[0];
else
return null;
}
/// <summary>
/// 判断取出的数据条数,str格式必须为 select count(*)
/// </summary>
public int GetSelectedCount(string sql, Dictionary<string, object> map = null)
{
object obj = GetSelectedObject(sql, map);
return ConvertUtil.ToInt(obj);
}
/// <summary>
/// 取单个数据,必须保证sql语句只取出一行,否者数据会被最后一行覆盖。
/// </summary>
public object GetSelectedObject(string sql, Dictionary<string, object> map = null)
{
object obj = new object();
DbDataReader sdr = GetDataReader(sql, map);
obj = (sdr.Read()) ? sdr[0] : obj;
sdr.Close();
return obj;
}
/// <summary>
/// 取单个字符串,必须保证sql语句只取出一行,否者数据会被最后一行覆盖。
/// </summary>
public string GetSelectedString(string sql, Dictionary<string, object> map = null)
{
object obj = GetSelectedObject(sql, map);
return obj.ToString();
}
/// <summary>
/// 获取执行Sql语句后受影响的行数
/// </summary>
public int GetExecutedNumber(string sql, Dictionary<string, object> map = null)
{
OdbcConnection conn = new OdbcConnection(ConnectString);
conn.Open();
OdbcCommand cmd = new OdbcCommand(sql, conn);
AddParameters(cmd, map);
int number = cmd.ExecuteNonQuery();
cmd.Dispose();
conn.Close();
conn.Dispose();
return number;
}
/// <summary>
/// 返回sql语句是否被执行
/// </summary>
public bool GetExecutedResult(string sql, Dictionary<string, object> map = null)
{
int count = GetExecutedNumber(sql, map);
return count > 0;
}
/// <summary>
/// 处理参数,防止报错
/// </summary>
private void AddParameters(OdbcCommand cmd, Dictionary<string, object> map)
{
if (map == null || map.Count == 0)
return;
List<OdbcParameter> paramList = new List<OdbcParameter>();
OdbcParameter thisParam;
foreach (KeyValuePair<string, object> kayValue in map)
{
if (kayValue.Value == null)
thisParam = new OdbcParameter(kayValue.Key, "");
else
thisParam = new OdbcParameter(kayValue.Key, kayValue.Value);
paramList.Add(thisParam);
}
cmd.Parameters.AddRange(paramList.ToArray());
}
/// <summary>
/// 获取所有表名
/// </summary>
public string[] GetTableNames()
{
OdbcConnection conn = new OdbcConnection(ConnectString);
conn.Open();
DataTable dt = conn.GetSchema("Tables");
conn.Close();
List<string> listName = new List<string>();
string name;
string[] sysKeys = { "MSys", "$'_", "$'Print_", "_xlnm" };
bool isTableName;
foreach (DataRow dr in dt.Rows)
{
name = dr["TABLE_NAME"].ToString();
isTableName = true;
foreach (string sysKey in sysKeys)
{
if (name.Contains(sysKey))
{
isTableName = false;
break;
}
}
if (isTableName)
listName.Add(name);
}
return listName.ToArray();
}
/// <summary>
/// 批量插入
/// </summary>
public void BulkInsert(DataTable table, string tableName)
{
int colCount = table.Columns.Count;
string columns = "";
for (int colIndex = 0; colIndex < colCount; colIndex++)
{
if (colIndex != 0)
{
columns += ",";
}
columns += "[" + table.Columns[colIndex].ColumnName + "]";
}
int rowCount = table.Rows.Count;
OdbcConnection conn = new OdbcConnection(ConnectString);
conn.Open();
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
{
string values = "";
Dictionary<string, object> map = new Dictionary<string, object>();
for (int colIndex = 0; colIndex < colCount; colIndex++)
{
string value = "@r" + rowIndex + "c" + colIndex;
map.Add(value, table.Rows[rowIndex][colIndex]);
if (colIndex != 0)
{
values += ",";
}
values += value;
}
string sql = "insert into [" + tableName + "] (" + columns + ") values (" + values + ");";
OdbcCommand cmd = new OdbcCommand(sql, conn);
AddParameters(cmd, map);
cmd.ExecuteNonQuery();
}
conn.Close();
}
/// <summary>
/// 连接字符串
/// value兼容空格,不要用"",''包裹
/// </summary>
public class ConnectStrings
{
/// <summary>
/// 通过名字获取连接字符串
/// </summary>
/// <param name="name">系统中配置过的ODBC</param>
public static string Name(string name)
{
return string.Format("Dsn={0};", name);
}
/// <summary>
/// 通过驱动名和文件路径获取连接字符串
/// </summary>
/// <param name="driver">驱动名</param>
/// <param name="path">文件路径</param>
public static string Diver(string driver, string path)
{
return string.Format("Driver={0};DBQ={1};", driver, path);
}
/// <summary>
/// Access07
/// </summary>
public static string AccessNew(string path)
{
return "Driver={Microsoft Access Driver (*.mdb, *.accdb)};" + string.Format("DBQ={0};", path);
}
/// <summary>
/// Paradox
/// </summary>
public static string Paradox(string floder)
{
return "Driver={Microsoft Paradox Driver (*.db )};" + string.Format("DBQ={0};", floder);
}
}
}
}
1.6、运行结果:
2、C#通过OleDb连接DBC数据库
2.1、看到Microsoft Paradox这两个字我就猜到OleDb应该能用,查MSDN文档,果不其然用的是03版的Access引擎
2.2、连接字符串:@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\MirDB;Extended Properties=Paradox 5.x;"
2.3、上代码:
using System;
namespace CommonUtils.Test
{
class Program
{
static void Main(string[] args)
{
DbOdbc odbc1 = new DbOdbc(@"Driver={Microsoft Paradox Driver (*.db )};DBQ=D:\MirDB;");
Console.WriteLine(odbc1.GetTableNames().ToJson());
DbOdbc odbc2 = new DbOdbc("Dsn=Paradox-HeroDb;");
Console.WriteLine(odbc2.GetTableNames().ToJson());
DbOle dbOle = new DbOle(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\MirDB;Extended Properties=Paradox 5.x;");
Console.WriteLine(dbOle.GetTableNames().ToJson());
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.OleDb;
namespace CommonUtils
{
/// <summary>
/// 访问Access,Excel,没有安装office可以安装microsoft office access database engine
/// </summary>
public class DbOle
{
/// <summary>
/// 连接字符串
/// </summary>
public string ConnectString { get; private set; }
/// <summary>
/// 初始化,获取连接字符串
/// </summary>
public DbOle(string connString)
{
ConnectString = connString;
}
/// <summary>
/// 是否可连接
/// </summary>
public bool CanConnect()
{
OleDbConnection conn = new OleDbConnection(ConnectString);
try
{
conn.Open();
conn.Close();
ConnectInfo = StringUtil.Success;
return true;
}
catch (Exception ex)
{
ConnectInfo = ex.Message;
return false;
}
finally
{
conn.Dispose();
}
}
/// <summary>
/// 连接信息
/// </summary>
public string ConnectInfo { get; private set; }
/// <summary>
/// 获取DataReader
/// </summary>
public DbDataReader GetDataReader(string sql, Dictionary<string, object> map = null)
{
OleDbConnection conn = new OleDbConnection(ConnectString);
conn.Open();
OleDbCommand cmd = new OleDbCommand(sql, conn);
AddParameters(cmd, map);
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
/// <summary>
/// 获取DataTable
/// </summary>
public DataTable GetDataTable(string sql, Dictionary<string, object> map = null)
{
OleDbConnection conn = new OleDbConnection(ConnectString);
conn.Open();
OleDbCommand cmd = new OleDbCommand(sql, conn);
AddParameters(cmd, map);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataTable table = new DataTable();
da.Fill(table);
conn.Close();
return table;
}
/// <summary>
/// 获取DataRow
/// </summary>
public DataRow GetDataRow(string sql, Dictionary<string, object> map = null)
{
DataTable table = GetDataTable(sql, map);
if (table.Rows.Count > 0)
return table.Rows[0];
else
return null;
}
/// <summary>
/// 获取DataSet
/// </summary>
public DataSet GetDataSet(string sql, Dictionary<string, object> map = null)
{
OleDbConnection conn = new OleDbConnection(ConnectString);
conn.Open();
OleDbCommand cmd = new OleDbCommand(sql, conn);
AddParameters(cmd, map);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
conn.Close();
return ds;
}
/// <summary>
/// 获取执行Sql语句后受影响的行数
/// </summary>
public int GetExecutedNumber(string sql, Dictionary<string, object> map = null)
{
OleDbConnection conn = new OleDbConnection(ConnectString);
conn.Open();
OleDbCommand cmd = new OleDbCommand(sql, conn);
AddParameters(cmd, map);
int i = cmd.ExecuteNonQuery();
conn.Close();
return i;
}
/// <summary>
/// 判断取出的数据条数,str格式必须为 select count(*)
/// </summary>
public int GetSelectedCount(string sql, Dictionary<string, object> map = null)
{
object obj = GetSelectedObject(sql, map);
return ConvertUtil.ToInt(obj);
}
/// <summary>
/// 取单个数据,必须保证sql语句只取出一行,否者数据会被最后一行覆盖。
/// </summary>
public object GetSelectedObject(string sql, Dictionary<string, object> map = null)
{
object obj = new object();
DbDataReader sdr = GetDataReader(sql, map);
obj = (sdr.Read()) ? sdr[0] : obj;
sdr.Close();
return obj;
}
/// <summary>
/// 取单个字符串,必须保证sql语句只取出一行,否者数据会被最后一行覆盖。
/// </summary>
public string GetSelectedString(string sql, Dictionary<string, object> map = null)
{
object obj = GetSelectedObject(sql, map);
return obj.ToString();
}
/// <summary>
/// 返回sql语句是否被执行
/// </summary>
public bool GetExecutedResult(string sql, Dictionary<string, object> map = null)
{
int i = GetExecutedNumber(sql, map);
return i > 0;
}
/// <summary>
/// 处理参数,防止报错
/// </summary>
private void AddParameters(OleDbCommand cmd, Dictionary<string, object> map)
{
if (map == null || map.Count == 0)
return;
List<OleDbParameter> paramList = new List<OleDbParameter>();
OleDbParameter thisParam;
foreach (KeyValuePair<string, object> keyValue in map)
{
if (keyValue.Value == null)
thisParam = new OleDbParameter(keyValue.Key, "");
else if (keyValue.Value.GetType() == typeof(DateTime))
thisParam = new OleDbParameter(keyValue.Key, ((DateTime)keyValue.Value).ToString("yyyy-MM-dd HH:mm:ss"));
else
thisParam = new OleDbParameter(keyValue.Key, keyValue.Value);
paramList.Add(thisParam);
}
cmd.Parameters.AddRange(paramList.ToArray());
}
/// <summary>
/// 获取所有表名
/// </summary>
public string[] GetTableNames()
{
OleDbConnection conn = new OleDbConnection(ConnectString);
conn.Open();
DataTable dt = conn.GetSchema("Tables");
conn.Close();
List<string> listName = new List<string>();
string name;
string[] sysKeys = { "MSys", "$'_", "$'Print_", "_xlnm" };
bool isTableName;
foreach (DataRow dr in dt.Rows)
{
name = dr["TABLE_NAME"].ToString();
isTableName = true;
foreach (string sysKey in sysKeys)
{
if (name.Contains(sysKey))
{
isTableName = false;
break;
}
}
if (isTableName)
listName.Add(name);
}
return listName.ToArray();
}
/// <summary>
/// 批量插入
/// </summary>
public void BulkInsert(DataTable table, string tableName)
{
int colCount = table.Columns.Count;
string columns = "";
for (int colIndex = 0; colIndex < colCount; colIndex++)
{
if (colIndex != 0)
{
columns += ",";
}
columns += "[" + table.Columns[colIndex].ColumnName + "]";
}
int rowCount = table.Rows.Count;
OleDbConnection conn = new OleDbConnection(ConnectString);
conn.Open();
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
{
string values = "";
Dictionary<string, object> map = new Dictionary<string, object>();
for (int colIndex = 0; colIndex < colCount; colIndex++)
{
string value = "@r" + rowIndex + "c" + colIndex;
map.Add(value, table.Rows[rowIndex][colIndex]);
if (colIndex != 0)
{
values += ",";
}
values += value;
}
string sql = "insert into [" + tableName + "] (" + columns + ") values (" + values + ");";
OleDbCommand cmd = new OleDbCommand(sql, conn);
AddParameters(cmd, map);
cmd.ExecuteNonQuery();
}
conn.Close();
}
/// <summary>
/// 连接字符串
/// 没有安装office可以安装microsoft office access database engine
/// AccessDatabaseEngine
/// 推荐下载2010版32位
/// https://www.microsoft.com/zh-cn/download/confirmation.aspx?id=13255
/// </summary>
public class ConnectStrings
{
/// <summary>
/// Access07
/// </summary>
public static string AccessNew(string path)
{
return string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source='{0}';", path);
}
/// <summary>
/// Access03
/// </summary>
public static string AccessOld(string path)
{
return string.Format("Provider=Microsoft.JET.OLEDB.4.0;Data Source='{0}';", path);
}
/// <summary>
/// Excel07 读取
/// </summary>
public static string ExcelNewReadOnly(string path)
{
return string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source='{0}';Extended Properties='Excel 12.0;HDR=YES;IMEX=1;';", path);
}
/// <summary>
/// Excel07 读写
/// </summary>
public static string ExcelNewReadWrite(string path)
{
return string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source='{0}';Extended Properties='Excel 12.0;HDR=YES;IMEX=0;';", path);
}
/// <summary>
/// Excel03 读取
/// </summary>
public static string ExcelOldReadOnly(string path)
{
return string.Format("Provider=Microsoft.JET.OLEDB.4.0;Data Source='{0}';Extended Properties='Excel 8.0;HDR=YES;IMEX=1;';", path);
}
/// <summary>
/// Excel03 读写
/// </summary>
public static string ExcelOldReadWrite(string path)
{
return string.Format("Provider=Microsoft.JET.OLEDB.4.0;Data Source='{0}';Extended Properties='Excel 8.0;HDR=YES;IMEX=0;';", path);
}
/// <summary>
/// Paradox引擎,传奇,征途等
/// </summary>
public static string Paradox(string floder)
{
return string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=Paradox 5.x;", floder);
}
}
}
}
2.4、运行结果: