Sql-Server

在 SSDT 中排除某些模式以及未命名的約束

  • March 29, 2022

任務

  1. 自動化數據庫部署(使用 CI/CD 部署 SSDT/dacpac)
  2. 該數據庫是第 3 方數據庫
  3. 它還包括我們自己定制的表/SP/Fn/Views 在單獨的模式中
  4. 將數據庫項目(dacpac)部署到生產時應排除第 3 方對象
  5. 感謝 Ed Elliott 的AgileSqlClub.DeploymentFilterContributor。使用 dll 成功過濾掉架構。

問題

  1. 3rd 方模式對象(表)在創建表時使用未命名的約束(預設/主鍵)定義。例子:
CREATE TABLE [3rdParty].[MainTable] 
(ID INT IDENTITY(1,1) NOT NULL,
CreateDate DATETIME DEFAULT(GETDATE()))  --There is no name given to default constraint
  1. 當我使用 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];
  1. 由於公司限制,我無法更改第 3 方架構
  2. 腳本中有很多行未命名的約束和約束。WITH CHECK CHECK

問題

  1. 我怎樣才能刪除DROP unnamed Constraint on 3rd 方模式的行?- 即使 dll 不包括 3rd 方模式,它仍然有這些未命名的約束腳本/部署。此外,它也不會將它們添加回來。
  2. 我如何能夠跳過/刪除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 看到了差異並想要刪除/創建。

命名您的約束,這不會發生。

引用自:https://dba.stackexchange.com/questions/268707