對出版資料庫進行結構變更

適用於:SQL ServerAzure SQL 受控執行個體

複寫支援對已發行物件進行大範圍的結構描述變更。 當您對 Microsoft SQL Server 發行者端適當的已發行物件進行下列任何結構描述變更時,依預設,該變更會傳播給所有的 SQL Server 訂閱者:

  • ALTER TABLE

  • ALTER TABLE SET LOCK ESCALATION 不應用於已啟用結構描述變更複寫,且拓撲包含 SQL Server 2005 (9.x) 或 SQL Server Compact 3.5 訂閱者的情況。

  • ALTER VIEW

  • ALTER PROCEDURE

  • ALTER FUNCTION

  • ALTER TRIGGER

    ALTER TRIGGER 只能用於資料操作語言(DML)觸發器,因為資料定義語言(DDL)觸發器無法被複製。

重要

你必須透過使用 Transact-SQL 或 SQL Server 管理物件(SMO)來更改資料表的結構。 當你在 SQL Server Management Studio 中更改結構時,Management Studio 會嘗試丟棄並重新建立該資料表。 你不能丟棄已發佈的物件,所以結構變更會失敗。

對於交易式複寫與合併式複寫,當「散發代理程式」或「合併代理程式」執行時,結構描述變更會以增量方式傳播。 對於快照式複寫,當訂閱者套用新的快照時,結構描述變更會傳播到訂閱者。 在快照式複寫中,每次發生同步處理時,結構描述的新副本便會傳送至「訂閱者」。 因此,所有對先前發佈物件的結構變更(不僅限於先前列出的)都會隨著每次同步自動傳遞。

如需有關在發行集中新增及移除文章的資訊,請參閱在現有發行集中新增及移除文章。

複寫結構描述變更

前面列出的架構變更預設會被複製。 如需有關停用結構描述變更複寫的詳細資訊,請參閱< Replicate Schema Changes>。

結構變更的考量

複寫結構描述變更時,請記住下列考量。

一般考量

  • 結構描述變更必須遵從由 Transact-SQL 規定的任何條件約束。 例如, ALTER TABLE 不允許你更改主鍵欄位。

  • 資料型別映射僅在初始快照時進行。 結構變更不會對應到先前版本的資料型態。 例如,如果你在 SQL Server 2012(11.x)中使用ALTER TABLE ADD datetime2 column,該資料型別不會對 SQL Server 2005(9.x)訂閱者轉換成 nvarchar。 在某些情況下,發行端上的結構描述變更會遭到封鎖。

  • 如果你設定出版品允許結構變更的傳播,無論你如何設定文章的相關結構選項,它都會傳播結構變更。 例如,如果您選擇不複寫某個資料表文章的外鍵條件約束,但之後在 Publisher 端執行 ALTER TABLE 命令,將外鍵加入該資料表,則該外鍵仍會加入 Subscriber 端的資料表中。 為避免此行為,請在發出指令前停用 ALTER TABLE 結構變更的傳播。

  • 僅在 Publisher 端進行結構變更,不要在 Subscribers 端進行(包括重發佈的 Subscribers)。 合併式複寫禁止在「訂閱者」端進行結構描述變更。 交易複製不會阻止這些變更,但這些變更可能導致複製失敗。

  • 依預設,傳播至重新發行訂閱者的變更會傳播至其訂閱者。

  • 如果結構變更涉及存在於 Publisher 但不存在於訂閱者身上的物件或約束,則結構變更在 Publisher 上成功,但在 Subscriber 上失敗。

  • 你在新增外鍵時參考的訂閱者上所有物件,必須與 Publisher 上對應的物件名稱和擁有者相同。

  • 明確新增、刪除或更改索引的行為不會被複製。 你需要在每個副本集上分別執行任何涉及明確指定索引的變更。 支援因約束而隱含建立的索引(例如主鍵約束)。

  • 不支援修改或刪除複製管理的身份欄位。 如需自動管理識別欄位的詳細資訊,請參閱複寫識別欄位。

  • 包含非確定性函數的結構變更不被支援,因為這可能導致 Publisher 與 Subscriber 的資料不同(稱為非收斂)。 例如,如果在「發行者」端發出下列命令: ALTER TABLE SalesOrderDetail ADD OrderDate DATETIME DEFAULT GETDATE(),則將命令複寫至「訂閱者」並執行此命令時,值會各不相同。 如需有關不具決定性函數的詳細資訊,請參閱< Deterministic and Nondeterministic Functions>。

  • 明確設定名稱限制。 如果你沒有明確命名限制,SQL Server 會為限制產生名稱,這些名稱在 Publisher 和每個訂閱者之間會有所不同。 這種差異在結構變更的複製過程中可能會造成問題。 例如,如果您在發行者端刪除某個資料行,且相依的條件約束也一併刪除,複寫便會嘗試在訂閱者端刪除該條件約束。 在訂閱者端刪除作業失敗,因為條件約束的名稱不同。 如果同步處理因條件約束名稱問題而失敗,請手動卸除訂閱者端的條件約束,然後重新執行合併代理程式。

  • 如果你發佈一個表格供複製,且你已經產生了發佈快照,就無法將該表格中的欄位改成 XML 的資料型別。 要更改欄位,必須先移除複製。

  • 在已發佈的資料表上執行 DDL 時,Read uncommitted 並不是支援的隔離層級。

  • 當對已發佈的物件執行結構描述變更時,請勿使用 SET CONTEXT_INFO 來修改交易的內容。

新增欄位

  • 若要在資料表中新增欄位,並將該欄位納入現有發行集中,請執行 ALTER TABLE <Table> ADD <Column>。 預設情況下,該資料行會複寫到所有訂閱者。 欄位必須允許 NULL 值或包含預設約束。 欲了解更多關於新增欄位的資訊,請參閱本文中的「合併複製」章節。

  • 若要在資料表中新增資料行,且不要將該資料行納入現有發行集,請停用結構描述變更的複寫,然後執行 ALTER TABLE <Table> ADD <Column>。

  • 若要在現有發行集中包含現有資料行,則使用 sp_articlecolumn (Transact-SQL)、sp_mergearticlecolumn (Transact-SQL) 或 [發行集屬性 - <發行集>] 對話方塊。

    如需詳細資訊,請參閱 Define and Modify a Column Filter。 此動作需要重新初始化訂閱。

  • 不支援在已發佈的資料表中新增識別資料行,因為當該資料行複寫到訂閱者時,可能會發生不收斂。 簽發者端識別欄位中的值,隨著受影響的資料表之資料列的實際儲存順序而不同。 資料列可能以不同方式儲存在訂閱者端;因此識別欄位的值可能與同資料列的不同。

刪除欄位

  • 若要從現有出版品中刪除欄位,並在 Publisher 的表格中刪除該欄位,執行 ALTER TABLE <Table> DROP <Column>。 預設情況下,該資料行會從所有訂閱者端的資料表中刪除。

  • 若要從現有發行集卸除資料行,但要將該資料行保留在「發行者」端的資料表中,則使用 sp_articlecolumn (Transact-SQL)、sp_mergearticlecolumn (Transact-SQL) 或 [發行集屬性 - <發行集>] 對話方塊。

    如需詳細資訊,請參閱 Define and Modify a Column Filter。 此動作需要產生新的快照。

  • 你不能用欄位來插入資料庫中任何出版物文章的過濾條款。

  • 在刪除已發表文章中的欄位時,請考慮欄位中可能影響資料庫的任何限制、索引或屬性。 例如:

    • 你無法從交易型出版物的文章中刪除主鍵中使用的欄位,因為複製會使用這些欄位。

    • 你無法從合併式發行集中之文章刪除 mstran_repl_version 欄位,也無法從支援可更新訂閱的交易式發行集中之文章刪除 rowguid 欄位,因為複寫會使用這些欄位。

    • 索引變動不會傳遞給訂閱者。 如果你在 Publisher 丟棄欄位,且丟棄依賴索引,索引掉落的結果不會被複製。 您應先在訂閱者端刪除索引,再在發行者端刪除資料行,如此當資料行刪除作業從發行者複寫到訂閱者時,才能成功完成。 如果同步處理因訂閱者端的索引而失敗,請手動卸除索引,然後重新執行合併代理程式。

    • 明確寫出限制條件,這樣你就可以省略它們。 欲了解更多資訊,請參閱本文前半部分的「一般考量」。

交易複製

  • 結構描述的變更會傳播到執行舊版 SQL Server 的訂閱者,但 DDL 陳述式應僅包含訂閱者上該版本所支援的語法。

    如果「訂閱者」重新發佈資料,唯一受支援的結構描述變更只有新增及刪除資料行。 在 Publisher 上使用 sp_repladdcolumn(Transact-SQL)和sp_repldropcolumn(Transact-SQL)來進行這些變更,而非 ALTER TABLE DDL 語法。

  • 架構變更不會被複製到非 SQL Server 訂閱者。

  • 架構變更不會從非 SQL Server 發行者傳播。

  • 你無法更改以表格形式複製的索引檢視。 你可以修改被複製為索引檢視的索引檢視,但修改它們會變成一般檢視,而非索引檢視。

  • 若發行集支援立即更新或佇列更新訂閱,請先讓系統進入靜止狀態,再進行結構描述變更:停止發行者與訂閱者上已發行資料表的所有活動,並讓所有擱置中的資料變更傳播到所有節點。 當結構變更傳遍所有節點後,已發佈的資料表即可恢復活動。

  • 如果發行集採用點對點拓撲,請先使系統進入靜止狀態,再進行結構描述變更。 如需詳細資訊,請參閱使複寫拓撲靜止化 (複寫 Transact-SQL 程式設計)。

  • 在表格中新增時間戳欄並將時間戳對應到 , binary(8) 會使所有活躍訂閱的文章重新初始化。

合併式複寫

  • 合併複寫如何處理結構變更,取決於發佈相容性等級,以及快照是設定為原生模式(預設)還是字元模式:

    • 若要複製結構變更,請將發佈相容性設定為至少 90RTM。 若訂閱者使用舊版本的 SQL Server 或相容性低於 90RTM,請使用 sp_repladdcolumn(Transact-SQL)和sp_repldropcolumn(Transact-SQL)來新增或刪除欄位。 不過,這些程序都已被取代。

    • 如果您嘗試將具有 SQL Server 2008 (10.0.x) 所引入資料類型的資料行新增到現有發行項,SQL Server 便具有以下行為:

      100RTM,原生快照 100RTM,字元快照 所有其他相容性層級
      hierarchyid 允許變更 封鎖變更 封鎖變更
      geography 及 geometry 允許變更 允許變更* 封鎖變更
      檔案資料流 允許變更 封鎖變更 封鎖變更
      date、 time、 datetime2和 datetimeoffset 允許變更 允許變更* 封鎖變更

      *SQL Server Compact 訂閱者會於訂閱者端轉換這些資料類型。

  • 如果套用結構描述變更時發生錯誤 (例如,因為新增參考了「訂閱者」端上不可用之資料表的外部索引鍵而發生的錯誤),則同步處理會失敗且必須重新初始化訂閱)。

  • 如果在聯結篩選或參數化篩選涉及的資料行上進行結構描述變更,則必須重新初始化所有訂閱並重新產生快照集。

  • 合併式複寫提供預存程序,讓您在進行疑難排解時略過結構描述變更。 如需詳細資訊,請參閱 sp_markpendingschemachange (Transact-SQL) 和 sp_enumeratependingschemachanges (Transact-SQL)。