C#.Net通過OleDb和ODBC連接DBC{Paradox(*.db)}數據庫,即傳奇DB Commander數據庫

前言:

一直沒用機會用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、運行結果:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章