[SQL]修改 BACPAC 內容讓 BACPAC 可以相容於舊版本

使用新版本的 SSMS 匯出 BACPAC 格式時,可能會因為匯出時帶有特別的版本資訊,要如何來做部分修改才能讓 SQL Server 匯入 ?

前一陣子因為有朋友詢問 Azure SQL Server 和 SQL Server 之間的匯出匯入,以及 SQL Server 和 SQL Server 不同版本間的匯出匯入的時候,整理了一篇「避開SQL Server資料庫備份檔無法降版使用的繞路做法」。這樣的做法的確幫了一些同事解決一些問題,但這一陣子 SSMS 16.5.3 版本的更新,造成在新版本的 SQL Server 2016 匯出的時候雖然可以順利匯出,但當我們將這樣的封裝檔愛匯入到 SQL Server 2014 的時候卻會出現類似下面的錯誤。

 

當我們點下 ERROR 看明細資料的話,從下面的錯誤訊息看起來,應該是 SSMS 在 BACPAC 產生的時候,產生特定的 SQL Server 2016 的語法,造成這樣的語法無法在 SQL Server 2014 上執行,導致失敗無法成功。

 

如同在另外一篇中所談到的「透過 DACPAC 來達到地端和雲端資料庫的版本控管」,我們可以將 BACPAC 的檔案將他的副檔名改成 .zip 之後,就可以將檔案內容解開出來。從 model.xml 中找到有問題的設定,看起來似乎把這些有問題的移除就好了。

<Element Type="SqlPermissionStatement" Name="[Grant.ViewAnyColumnEncryptionKeyDefinition.Database].[public].[dbo]">
	<Property Name="Permission" Value="1108" />
	<Relationship Name="Grantee">
		<Entry>
			<References ExternalSource="BuiltIns" Name="[public]" />
		</Entry>
	</Relationship>
	<Relationship Name="SecuredObject">
		<Entry>
			<References Disambiguator="1" />
		</Entry>
	</Relationship>
</Element>
<Element Type="SqlPermissionStatement" Name="[Grant.ViewAnyColumnMasterKeyDefinition.Database].[public].[dbo]">
	<Property Name="Permission" Value="1107" />
	<Relationship Name="Grantee">
		<Entry>
			<References ExternalSource="BuiltIns" Name="[public]" />
		</Entry>
	</Relationship>
	<Relationship Name="SecuredObject">
		<Entry>
			<References Disambiguator="1" />
		</Entry>
	</Relationship>
</Element>

 

當我們把這個的新的 BACPAC給匯入的時候,結果發生悲劇了,看來在第一關的檢核就沒有通過了

從細部的錯誤訊息看起來,當我們單純只修改 model.xml 的時候,在壓縮檔案內有存放檔案的檢核碼,因此當我們單純只修改 model.xml 的時候,就會發生驗證錯誤了。

因此仔細找一下檔案,果然在 Origin.xml 內有存放這個 Checksum 值,看來似乎有點麻煩,要怎麼來計算出這個值呢 ?

<ExportStatistics>
	<SourceDatabaseSize>1756752</SourceDatabaseSize>
	<TableRowCountTotalTag>3556709</TableRowCountTotalTag>
</ExportStatistics>
<Checksums>
	<Checksum Uri="/model.xml">4C178E8DEB80854EC469A5DDD8D5AEA6A862829DB7A28F830C4CD9D776770300</Checksum>
</Checksums>
<ModelSchemaVersion>2.6</ModelSchemaVersion>

 

好在運氣還算不錯,Gert Drapers 在 Github 上有人有分享了一個專案 ( https://github.com/gertd ) ,從中有透露出 Checksum 怎麼來計算,也寫好了一個簡單的應用程式,只可惜那個上面的檔案有點年代了,因此需要自己去把 source 抓回來重新編譯一下,就可以重新編譯一個出來使用了。

 

於是按照程式的說明,利用 dacchksum 的工具程式,後面利用 /i: 的參數指定我們的 BACPAC 的檔案,就會如下圖的告訴我們正確的檢核碼應該是多少,此時我們將這個計算出來的值,放回到 Origin.xml 的檔案內,看起來就大功告成了。

於是立馬實際測試一下,果然是沒有問題的,有需要的朋友可以來測試看看囉。

PS. 因為現在點部落不允許文章中夾帶檔案放在網站上,加上又有人會擔心是否夾帶的檔案會有病毒,因此有需要的朋友就前往 Gert Drapers 在 Github 的倉庫,把檔案抓回來自己編譯一下囉。