使用 SSDT 發行功能產生的指令碼,是否會依照資料表的關聯依序產生?

本文將介紹使用 SSDT 發行功能產生的指令碼,是否會依照資料表的關聯依序產生。

【情境描述】

有朋友 No. 18 在筆者的使用 SSDT 來管理資料庫物件 一文中問到【使用 SSDT 發行功能產生的指令碼,是否會依照資料表的關聯依序產生】,老實說筆者也沒注意到這個問題的細節,但是就 SQL Server 建立資料表時,會檢查 Foreign Key 所參考的 Primary Key 是否存在的機制來說,以 Northwind 資料庫為例,由於 Order Details 資料表會以 OrderID 資料行關連到 Orders 資料表,並以 ProductID 資料行關連到 Products 資料表,所以假設您在建立 Orders 和 Products 資料表前,就以下列指令碼嘗試建立 Order Details 資料表:

CREATE TABLE [dbo].[Order Details] (
    [OrderID]   INT      NOT NULL,
    [ProductID] INT      NOT NULL,
    [UnitPrice] MONEY    CONSTRAINT [DF_Order_Details_UnitPrice] DEFAULT (0) NOT NULL,
    [Quantity]  SMALLINT CONSTRAINT [DF_Order_Details_Quantity] DEFAULT (1) NOT NULL,
    [Discount]  REAL     CONSTRAINT [DF_Order_Details_Discount] DEFAULT (0) NOT NULL,
    CONSTRAINT [PK_Order_Details] PRIMARY KEY CLUSTERED ([OrderID] ASC, [ProductID] ASC),
    CONSTRAINT [CK_Discount] CHECK ([Discount] >= 0 and [Discount] <= 1),
    CONSTRAINT [CK_Quantity] CHECK ([Quantity] > 0),
    CONSTRAINT [CK_UnitPrice] CHECK ([UnitPrice] >= 0),
    CONSTRAINT [FK_Order_Details_Orders] FOREIGN KEY ([OrderID]) REFERENCES [dbo].[Orders] ([OrderID]),
    CONSTRAINT [FK_Order_Details_Products] FOREIGN KEY ([ProductID]) REFERENCES [dbo].[Products] ([ProductID])
);

您會遇到如下圖的錯誤:

image

使用 SSDT 部署資料庫專案時,雖然在方案總管中看不出資料庫物件的先後順序,但以 SSDT 貼心的設計看來,應該會考慮到這個問題才是。基於前述的假設,筆者實際來驗證是否 SSDT 發行指令碼時,會依照資料表的關聯依序建立對應的指令碼。

實作步驟

首先在方案總管中的資料庫專案名稱上按滑鼠右鍵,選擇【發行】。

image

於【發行資料庫】視窗點選編輯,輸入目標資料庫的相關資訊後,點選【產生指令碼】,您也可以依照您的需求修改指令碼的檔案名稱。

image

接著您可以在資料工具作業視窗中看到產生指令碼的進度,產生完畢之後會自動開啟您在上一步驟所設定的發行指令碼,或是您也可以點選下圖紅色框框處的連結來開啟發行指令碼。

SNAGHTML565882e

您可以從產生的指令碼看來,SSDT 會先產生資料表等資料庫物件的指令碼,然後才去建立預設值、Foreign Key 以及 Constraint,最後才是輪到基於基礎資料表的 View、Stored Procedure 等資料庫物件(如下圖)。

image

參考資料

-使用 SSDT 來管理資料庫物件