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

SQL Server 資料庫導庫腳本:跨帳套資料遷移的靈活方案

     編輯:關於SqlServer

適用場景

  • ERP 類國產軟體(K/3、U8 等)帳套損壞無法修復
  • 新建同結構帳套,需將舊資料導入新帳套
  • DTS 導入導出不夠靈活,需精細控制導入順序、約束處理

核心邏輯:存儲程序 sp_ExportDatabase

CREATE PROCEDURE [sp_ExportDatabase] 
    @SourceDB VARCHAR(100)  -- 來源資料庫名稱
AS
BEGIN
    SET NOCOUNT ON;
    
    -- 1. 禁用所有約束與觸發器(避免外鍵阻擋、觸發器副作用)
    -- 2. 清空目標表資料
    -- 3. 動態建構欄位清單(排除計算欄、timestamp 等)
    -- 4. 處理 IDENTITY 欄位:SET IDENTITY_INSERT ON/OFF
    -- 5. 執行 INSERT ... SELECT 跨庫複製
    -- 6. 重新啟用約束與觸發器
END

關鍵技術細節

1. 游標遍歷使用者表

DECLARE Ctb CURSOR FOR
SELECT name, id FROM sysobjects
WHERE xtype = 'U' 
  AND name IN (/* 可指定表清單,跳過損壞表 */)
ORDER BY name;

2. 三階段處理流程

階段操作目的
Phase 1 DISABLE TRIGGER ALL + NOCHECK CONSTRAINT ALL 移除寫入阻礙
Phase 2 DELETE 目標表 → 動態建構 INSERT ... SELECT 資料遷移核心
Phase 3 ENABLE TRIGGER ALL + CHECK CONSTRAINT ALL 恢復資料完整性

3. IDENTITY 欄位特殊處理

IF EXISTS (SELECT * FROM syscolumns WHERE id = @tid AND status = 0x80)
BEGIN
    -- 0x80 表示 IDENTITY 欄位
    SET @sql = 'SET IDENTITY_INSERT ' + @Utb + ' ON ' + @sql;
    EXEC(@sql);
    EXEC('SET IDENTITY_INSERT ' + @Utb + ' OFF');
END

4. 計算欄與 timestamp 自動排除

DECLARE Clu CURSOR FOR
SELECT name FROM syscolumns 
WHERE id = @tid 
  AND iscomputed = 0 
  AND xtype <> 189;  -- 189 = timestamp

使用方式

  1. 在目標(新)資料庫建立此存儲程序
  2. 執行:EXEC sp_ExportDatabase 'SourceDB_Name'
  3. 觀察訊息輸出確認各表導入狀態

優缺點分析

優點缺點/風險
完全掌控導入順序與邏輯 需理解來源/目標結構差異
可跳過損壞表繼續導入 大量資料執行時間較長
自動處理 IDENTITY/計算欄 跨版本結構差異需手動調整
無需額外工具,純 T-SQL 不支援資料轉換/清洗邏輯

現代化建議

  • SQL Server 2005+ 可改用 MERGE 實現 UPSERT 邏輯
  • SSIS 套件提供視覺化、可重用、可參數化的更佳替代
  • 大型遷移建議:唯讀備份 + 記錄檔傳送 或 AlwaysOn 可用性群組 同步後再切換

此腳本展示了「動態 SQL + 游標 + 系統表元資料」的經典組合,理解其原理有助於掌握資料庫元編程技術。

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