【SQL Server】資料庫架構比對

最近工作需要比對前次幫客戶建置的資料庫,並將新專案的資料表補齊,但因為無法直接操作客戶的正式機,且前人並沒有對前次建置的資料庫進行合式的紀錄,因此阿猩這幾天整理了一些可以完成工作的作法。

 

資料層應用程式


資料層應用程式(Data-tier Application - DAC)
資料層應用程式包含所有SQL Server物件,包含Table、View、Stored Procedure等,又可依內容分為兩種檔案類型

  1. .dacpac:僅資料庫結構描述
  2. .bacpac:資料庫結構描述 + 資料

    如果要還原整個資料庫或是新增少量Table及資料,使用.bak產生Insert指令碼會方便許多。但目前阿猩遇到的問題是,正式機已上線一陣子,如果使用.bak會有問題,要新增的Table,又必須先跟正式機比對後,才能確定哪些Table或資料需要新增或異動,接著讓我們來看看如何利用資料層應用程式來解決這部分的問題。


取得.dacpac檔案流程
 

按下擷取資料層應用程式
下一步
設定檔案名稱及儲存路徑
成功畫面
使用Visual Studio新增結構比較
選擇.dacpac檔案來源
選擇來源
差異分析

 

人算不如天算


Error SQL71501 
正當阿猩很開心,開始將所有資料庫都匯出結構描述時,好幾個資料庫居然匯出失敗,錯誤訊息會像是

Error SQL71561: 驗證元素 [dbo].[vwTest].[Memo] 時發生錯誤: 計算資料行: [dbo].[ vwTest].[Memo] 包含 物件 [DiffCompare].[dbo].[Test].[Memo] 無法解析的參考。

原因是,進行匯出結構描述時,會比對Table欄位是否一致,如果不一致,就會發生Error SQL71501錯誤訊息。在阿猩公司的問題就是,某個View使用了Memo欄位進行篩選,但在[DiffCompare].[dbo].[Test] Table中找不到Memo欄位了,只要將兩邊統一後,這個問題就解決了。


Error SQL71561
另一個資料庫遇到錯誤代碼是Error SQL71561,檢驗欄位無誤後,阿猩開始懷疑人生,這個問題是因為,在A資料庫中建立View,而View使用的是B資料庫的Table,因此程式無法比對兩者Schema,後來找到了SqlPackage 來解決這個問題(參考1)。

SqlPackage 
下載並安裝SqlPackage(參考2),目前預設安裝路徑是「C:\Program Files\Microsoft SQL Server\160\DAC\bin」,執行

SqlPackage.exe /Action:extract /SourceServerName:$ServerName /SourceDatabaseName:$DbName /tf:"C:\Users\xxx.dacpac

Action:exreact 表示要執行匯出的動作
SorceServerName:將$ServerName改為要使用的Server,如localhost
SorceDatabaseName:將$DbName改為要匯出的資料庫
tf:目標路徑及檔名

因SqlPackage不會對引用的資料庫進行Schema檢查,就可以成功取得.dacpac檔啦,但事後還是要人工檢查一下,兩邊Schema是否相同。

 

產出Insert Into語法


在成功建立所有Table之後,有些資料是屬於固定參數,因此也得將資料寫進正式機資料庫內,這裡阿猩試過過2種方法,可以快速產出Insert語句

  1. SSMS內建的「產生指令碼
  2. SQLDumper

如果想用Table篩選,並寫入全部資料,產生指令碼是個不錯的選擇,如果想針對Table中,篩選特定資料,SQLDumper可以下Where指令會更方便,有興趣自行Google。

 

參考資料

  1. https://blog.miniasp.com/post/2021/10/14/Using-SqlPackage-to-Extract-DeployReport-DriftReport-Publish-Script-Export-Import
  2. https://docs.microsoft.com/zh-tw/sql/tools/sqlpackage/sqlpackage-download?view=sql-server-ver16