首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

C# 實作 SQL Server 2005 到 Oracle 10g 資料遷移完整程式碼

     編輯:Oracle 資料庫基礎

專案背景

需將 SQL Server 2005 多張資料表資料遷移至 Oracle 10g,保留結構與資料完整性。採用 C# (ADO.NET) 批次搬移,支援交易控制與進度顯示。

核心程式碼架構

using System;
using System.Data;
using System.Data.SqlClient;
using Oracle.DataAccess.Client; // ODP.NET

namespace DataMigration
{
    public class ImportExportData
    {
        private readonly string _sqlConnStr = "Data Source=localhost;Initial Catalog=UserCenterV32;Integrated Security=SSPI;";
        private readonly string _oraConnStr = "Data Source=Oracle11;User Id=DBO_USERCENTERV32;Password=DBO_USERCENTERV32;";

        public void ExportAll()
        {
            // 依相依順序列出需遷移表名
            string[] tables = { "Base_Sequence", "Base_Module", "Base_Role" /* ...更多表*/ };

            foreach (var tbl in tables)
                ExportTable(tbl);
        }

        public void ExportTable(string tableName, string customSql = null)
        {
            DataTable dt;
            using (var sqlConn = new SqlConnection(_sqlConnStr))
            using (var sqlCmd = new SqlCommand(customSql ?? $"SELECT * FROM {tableName}", sqlConn))
            {
                sqlConn.Open();
                using (var adapter = new SqlDataAdapter(sqlCmd))
                {
                    dt = new DataTable(tableName);
                    adapter.Fill(dt);
                }
            }

            using (var oraConn = new OracleConnection(_oraConnStr))
            {
                oraConn.Open();
                using (var tx = oraConn.BeginTransaction())
                {
                    try
                    {
                        // 1. 清空目標表
                        using (var truncateCmd = new OracleCommand($"TRUNCATE TABLE {tableName}", oraConn, tx))
                            truncateCmd.ExecuteNonQuery();

                        // 2. 批次插入
                        string cols = string.Join(",", dt.Columns.Cast().Select(c => c.ColumnName));
                        string params = string.Join(",", dt.Columns.Cast().Select(c => ":" + c.ColumnName));
                        string insertSql = $"INSERT INTO {tableName} ({cols}) VALUES ({params})";

                        using (var insCmd = new OracleCommand(insertSql, oraConn, tx))
                        {
                            // 建立參數
                            foreach (DataColumn col in dt.Columns)
                                insCmd.Parameters.Add(col.ColumnName, GetOracleType(col.DataType));

                            foreach (DataRow row in dt.Rows)
                            {
                                for (int i = 0; i < dt.Columns.Count; i++)
                                    insCmd.Parameters[i].Value = row[i] ?? DBNull.Value;
                                insCmd.ExecuteNonQuery();
                            }
                        }

                        tx.Commit();
                        Console.WriteLine($"表 {tableName} 遷移完成,共 {dt.Rows.Count} 筆。");
                    }
                    catch (Exception ex)
                    {
                        tx.Rollback();
                        Console.WriteLine($"表 {tableName} 遷移失敗: {ex.Message}");
                        throw;
                    }
                }
            }
        }

        private OracleDbType GetOracleType(Type netType)
        {
            // 簡易型別對應,實務需依實際欄位精細對應
            if (netType == typeof(string)) return OracleDbType.Varchar2;
            if (netType == typeof(int) || netType == typeof(long)) return OracleDbType.Int64;
            if (netType == typeof(DateTime)) return OracleDbType.Date;
            if (netType == typeof(decimal)) return OracleDbType.Decimal;
            return OracleDbType.Varchar2;
        }
    }
}

關鍵技術點解析

環節處理策略
交易控制Oracle 端開啟交易,全表插入成功才 Commit,失敗 Rollback 保證原子性
大量資料效能建議改用 OracleBulkCopy (ODP.NET 2.0+) 或陣列繫結 ArrayBindCount 批次寫入
型別對應SQL Server datetime → Oracle DATE;uniqueidentifier → RAW(16);bit → NUMBER(1)
身分欄位Oracle 12c 前無 Identity,需建立 Sequence + Trigger 或手動指派
編碼問題連線字串加 `Unicode=True`,確保中文不亂碼

進階優化建議

  • 使用 OracleBulkCopy 替代逐筆 `ExecuteNonQuery`,效能提升 10-50 倍。
  • 並行處理:將大表按主鍵範圍分割,多執行緒平行遷移。
  • 斷點續傳:記錄已遷移主鍵最大值,支援中斷後續跑。
  • 資料驗證:遷移後跑 `COUNT(*)`、`CHECKSUM` 比對雙邊一致性。

結語

以 C# 撰寫異構資料庫遷移工具,靈活度高、易維護。核心在於交易保護、型別精確對應、大量資料批次寫入三大支柱。生產環境建議採用 OracleBulkCopy + 並行化架構,並建立完整驗證與回滾機制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved