在 SSDT 中排除某些模式以及未命名的約束
任務
- 自動化數據庫部署(使用 CI/CD 部署 SSDT/dacpac)
- 該數據庫是第 3 方數據庫
- 它還包括我們自己定制的表/SP/Fn/Views 在單獨的模式中
- 將數據庫項目(dacpac)部署到生產時應排除第 3 方對象
- 感謝 Ed Elliott 的AgileSqlClub.DeploymentFilterContributor。使用 dll 成功過濾掉架構。
問題
- 3rd 方模式對象(表)在創建表時使用未命名的約束(預設/主鍵)定義。例子:
CREATE TABLE [3rdParty].[MainTable] (ID INT IDENTITY(1,1) NOT NULL, CreateDate DATETIME DEFAULT(GETDATE())) --There is no name given to default constraint
- 當我使用 sqlpackage.exe 生成部署腳本時,我在生成的腳本中看到以下語句。
使用以下方法生成腳本:
“C:\Program Files\Microsoft SQL Server\150\DAC\bin\sqlpackage.exe” /action:script /sourcefile:C:\Users\User123\source\repos\DBProject\DBProject\bin\Debug\DBProject.dacpac /TargetConnectionString:“數據源=MyServer;初始目錄=MSSQLDatabase;Trusted_Connection=True” /p:AdditionalDeploymentContributorPaths=“C:\Program Files\Microsoft SQL Server\150\DAC\bin\AgileSqlClub.SqlPackageFilter.dll” /p:AdditionalDeploymentContributors =AgileSqlClub.DeploymentFilterContributor /p:AdditionalDeploymentContributorArguments=“SqlPackageFilter=IgnoreSchema(3rdParty)” /outputpath:“c:\temp\script_AfterDLL.sql”
腳本輸出:
/* Deployment script for MyDatabase This code was generated by a tool. Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. */ ... ... GO PRINT N'Dropping unnamed constraint on [3rdParty].[MainTable]...'; GO ALTER TABLE [3rdParty].[MainTable] DROP CONSTRAINT [DF__MainTabl__Crea__59463169]; ... ... ...(towards the end of the script) ALTER TABLE [3rdParty].[MainTable_2] WITH CHECK CHECK CONSTRAINT [fk_518_t_44_t_9];
- 由於公司限制,我無法更改第 3 方架構
- 腳本中有很多行未命名的約束和約束。
WITH CHECK CHECK
問題
- 我怎樣才能刪除DROP unnamed Constraint on 3rd 方模式的行?- 即使 dll 不包括 3rd 方模式,它仍然有這些未命名的約束腳本/部署。此外,它也不會將它們添加回來。
- 我如何能夠跳過/刪除
WITH CHECK CHECK CONSTRAINT
第 3 方模式的生成另外,我發現了另一個問題。由於以下原因,部署將不會成功:
檢測到行。架構更新正在終止,因為可能會發生數據失去
輸出
/* The column [3rdParty].[MainTable_1].[Col1] is being dropped, data loss could occur. The column [3rdParty].[MainTable_1].[Col2] is being dropped, data loss could occur. The column [3rdParty].[MainTable_1].[Col3] is being dropped, data loss could occur. The column [3rdParty].[MainTable_1].[Col4] is being dropped, data loss could occur. */ IF EXISTS (select top 1 1 from [3rdParty].[MainTable_1]) RAISERROR (N'Rows were detected. The schema update is terminating because data loss might occur.', 16, 127) WITH NOWAIT GO
我嘗試了各種參數組合,但沒有運氣。
/p:ExcludeObjectType=Defaults
或/p:DropObjectsNotInSource=False /p:DoNotDropObjectType=Defaults
等等。
您可以使用實用程序DacpacTool從 dacpac 文件中完全刪除模式 - 我編寫它就是為了做到這一點(除其他外)。到目前為止,它的邊緣相當粗糙,但它確實有效。
- 從目標數據庫中提取 dacpac 到
MSSQLDatabase.dacpac
- 用一行創建一個文件 blacklist.txt:
<References Name="\[SchemaThatYouWantRemoved]
DacpacTool.exe filter -f MSSQLDatabase.dacpac -b blacklist.txt
DacpacTool.exe filter -f DBProject.dacpac -b blacklist.txt
- 編寫兩個 dacpac 之間的差異腳本。不再需要 DeploymentFilterContributor:
sqlpackage.exe /action:script /sourcefile:DBProject.dacpac /TargetFile:"MSSQLDatabase.dacpac" /outputpath:"c:\temp\script_AfterDLL.sql"
SSDT 刪除未命名的約束是告訴您在創建約束時沒有命名約束。在部署期間,它們會被 SQL 分配一個動態名稱。由於項目不包含動態名稱,SQLPackage 看到了差異並想要刪除/創建。
命名您的約束,這不會發生。