2010-05-30 65 views
3

我已經安裝與Microsoft Sync Framework同步,現在我需要將字段添加到表中。 如何重新設置數據庫?Microsoft Sync Framework - 如何在模式更改後重新配置表(或整個範圍)?

的設置是非常簡單的:

  • 兩個SQL Express 2008的服務器
  • 範圍包括整個數據庫
  • 通過直接訪問使用Microsoft同步框架2.0
  • 同步。使用標準新版SqlSyncProvider

我是否在兩端進行結構更改?或者,我是否只更換一臺服務器,並讓Sync Framework以某種方式傳播更改?

我需要刪除_tracking表和/或存儲過程嗎?觸發器怎麼樣?

有沒有人使用過Sync Framework?請幫忙。

回答

2

其實,我貼在我的博客http://myazurejourney.blogspot.com/

它有幾個步驟,這絕對是一個黑客我自己的答案。但它的工作。

檢查一下。告訴我你的想法

+0

一個重要的優勢,只能重新調配,你改變的是,你把所有的元數據範圍和所有參與範圍 – Rabbi 2010-06-16 12:20:37

0

去除範圍和重新設置...使用此代碼刪除範圍

private void RemoveScope(SqlConnection Conn, bool ShowAlert) 
{ 
    foreach (var table in _settings.TablesToSync) 
    { 
     SqlCommand dropTracking = new SqlCommand(@" 
      IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[" + table.Key + @"_tracking]') AND type in (N'U')) 
      DROP TABLE [dbo].[" + table.Key + "_tracking]", Conn); 
     dropTracking.ExecuteNonQuery(); 

     SqlCommand dropTriggers = new SqlCommand(@" 
      IF EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[" + table.Key + @"_delete_trigger]')) 
      DROP TRIGGER [dbo].[" + table.Key + @"_delete_trigger]; 

      IF EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[" + table.Key + @"_insert_trigger]')) 
      DROP TRIGGER [dbo].[" + table.Key + @"_insert_trigger]; 

      IF EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[" + table.Key + @"_update_trigger]')) 
      DROP TRIGGER [dbo].[" + table.Key + @"_update_trigger]; 
     ", Conn); 
     dropTriggers.ExecuteNonQuery(); 

     SqlCommand dropStoredProc = new SqlCommand(@" 
      IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[" + table.Key + @"_delete]') AND type in (N'P', N'PC')) 
      DROP PROCEDURE [dbo].[" + table.Key + @"_delete]; 

      IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[" + table.Key + @"_deletemetadata]') AND type in (N'P', N'PC')) 
      DROP PROCEDURE [dbo].[" + table.Key + @"_deletemetadata]; 

      IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[" + table.Key + @"_insert]') AND type in (N'P', N'PC')) 
      DROP PROCEDURE [dbo].[" + table.Key + @"_insert]; 

      IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[" + table.Key + @"_insertmetadata]') AND type in (N'P', N'PC')) 
      DROP PROCEDURE [dbo].[" + table.Key + @"_insertmetadata]; 

      IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[" + table.Key + @"_selectchanges]') AND type in (N'P', N'PC')) 
      DROP PROCEDURE [dbo].[" + table.Key + @"_selectchanges]; 

      IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[" + table.Key + @"_selectrow]') AND type in (N'P', N'PC')) 
      DROP PROCEDURE [dbo].[" + table.Key + @"_selectrow]; 

      IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[" + table.Key + @"_update]') AND type in (N'P', N'PC')) 
      DROP PROCEDURE [dbo].[" + table.Key + @"_update]; 

      IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[" + table.Key + @"_updatemetadata]') AND type in (N'P', N'PC')) 
      DROP PROCEDURE [dbo].[" + table.Key + @"_updatemetadata]; 
     ", Conn); 
     dropStoredProc.ExecuteNonQuery(); 
    } 

    SqlCommand getScopeGuid = new SqlCommand(@" 
      USE [" + Conn.Database + @"] 
      SELECT scope_config_id FROM scope_info WHERE scope_name = '" + _settings.ScopeName + "'", Conn); 

    var reader = getScopeGuid.ExecuteReader(); 

    if (reader.HasRows) 
    { 
     reader.Read(); 

     var id = reader.GetGuid(0); 

     reader.Close(); 

     SqlCommand deleteScope = new SqlCommand(@" 
       DELETE FROM scope_info WHERE scope_config_id = '" + id + @"'; 
       DELETE FROM scope_config WHERE config_id = '" + id + @"'; 
      ", Conn); 
     deleteScope.ExecuteNonQuery(); 
    } 

    if(ShowAlert) 
     MessageBox.Show("Scope has been removed"); 
} 
+1

B中的其它表的表「H ÿ你已經有了如何完全從數據庫中獲取同步MetaData的基本思路。 首先我想指出要小心。如果您有多個範圍指向相同的表。您提供的代碼將刪除範圍之間共享的觸發器,sprocs等,當您嘗試執行其他範圍時,您將遇到麻煩。 我很驚訝,這樣的功能不包括在框架中。也許作爲「社區」,我們可以組合一個實用工具,其中包括簡單的輔助方法,比如這個和我在博客上發佈的輔助方法。 – Rabbi 2010-06-16 11:56:30

+1

接下來我想對您的編程發表點評: 1.您使用傳遞參數的反模式來顯示消息框。如果調用者知道足以傳遞該參數,那麼它應該只是自己處理UI,並在該函數返回後顯示消息框。 2.當你神奇地獲得_settings對象時,conn是一個有趣的選擇。如果可以的話,我會考慮以相反的方式來做 - 設置應該是參數(這就是你正在處理的),Conn應該通過IOC或成員變量來訪問。 – Rabbi 2010-06-16 12:06:59

+0

3.爲什麼「USE [」+ Conn.Database + @「]」?如果您從連接中獲取數據庫的名稱。那麼它必須是連接的當前數據庫。所以這完全是多餘的。 – Rabbi 2010-06-16 12:08:48

0

我用Montago的解決方案,但它轉換成做了工作的SQL代碼爲了我。可以自由地使用它,我希望它可以幫助你:)

USE DatabaseName 
GO 

DECLARE @sqlDrop VARCHAR(1000) 
SET @sqlDrop = 'IF EXISTS (SELECT * FROM #table# WHERE object_id = OBJECT_ID(''#name#'')) DROP #what# #name#' 
DECLARE @sqlCommand VARCHAR(1000) 

DECLARE @id INT 
SET @id = 0 
DECLARE @name SYSNAME 
DECLARE @prev INT 

WHILE 1 = 1 
    BEGIN 
     /* find traces of synchronization */ 

     -- to be sure that id changed 
     SET @prev = @id 

     -- get the next table 
     SELECT TOP 1 
      @id = object_id, 
      @name = name 
     FROM sys.tables 
     WHERE object_id > @id 
     ORDER BY object_id 

     -- confirm that there is next table 
     IF @id = @prev 
     BREAK 

     /* remove traces of synchronization */ 

     -- remove table 
     SET @sqlCommand = @sqlDrop 
     SET @sqlCommand = REPLACE(@sqlCommand, '#table#', 'sys.tables') 
     SET @sqlCommand = REPLACE(@sqlCommand, '#name#', @name + '_tracking') 
     SET @sqlCommand = REPLACE(@sqlCommand, '#what#', 'TABLE') 
     EXEC (@sqlCommand) 

     -- remove triggers 
     SET @sqlCommand = @sqlDrop 
     SET @sqlCommand = REPLACE(@sqlCommand, '#table#', 'sys.triggers') 
     SET @sqlCommand = REPLACE(@sqlCommand, '#name#', @name + '_delete_trigger') 
     SET @sqlCommand = REPLACE(@sqlCommand, '#what#', 'TRIGGER') 
     EXEC (@sqlCommand) 
     SET @sqlCommand = REPLACE(@sqlCommand, '_delete_trigger', '_insert_trigger') 
     EXEC (@sqlCommand) 
     SET @sqlCommand = REPLACE(@sqlCommand, '_insert_trigger', '_update_trigger') 
     EXEC (@sqlCommand) 

     -- remove stored procedures 
     SET @sqlCommand = @sqlDrop 
     SET @sqlCommand = REPLACE(@sqlCommand, '#table#', 'sys.procedures') 
     SET @sqlCommand = REPLACE(@sqlCommand, '#name#', @name + '_delete') 
     SET @sqlCommand = REPLACE(@sqlCommand, '#what#', 'PROCEDURE') 
     EXEC (@sqlCommand) 
     SET @sqlCommand = REPLACE(@sqlCommand, '_delete', '_deletemetadata') 
     EXEC (@sqlCommand) 
     SET @sqlCommand = REPLACE(@sqlCommand, '_deletemetadata', '_insert') 
     EXEC (@sqlCommand) 
     SET @sqlCommand = REPLACE(@sqlCommand, '_insert', '_insertmetadata') 
     EXEC (@sqlCommand) 
     SET @sqlCommand = REPLACE(@sqlCommand, '_insertmetadata', '_selectchanges') 
     EXEC (@sqlCommand) 
     SET @sqlCommand = REPLACE(@sqlCommand, '_selectchanges', '_selectrow') 
     EXEC (@sqlCommand) 
     SET @sqlCommand = REPLACE(@sqlCommand, '_selectrow', '_update') 
     EXEC (@sqlCommand) 
     SET @sqlCommand = REPLACE(@sqlCommand, '_update', '_updatemetadata') 
     EXEC (@sqlCommand) 
     SET @sqlCommand = REPLACE(@sqlCommand, '_updatemetadata', '_bulkdelete') 
     EXEC (@sqlCommand) 
     SET @sqlCommand = REPLACE(@sqlCommand, '_bulkdelete', '_bulkinsert') 
     EXEC (@sqlCommand) 
     SET @sqlCommand = REPLACE(@sqlCommand, '_bulkinsert', '_bulkupdate') 
     EXEC (@sqlCommand) 

    END 

-- remove scope and schema tables 
SET @sqlCommand = @sqlDrop 
SET @sqlCommand = REPLACE(@sqlCommand, '#table#', 'sys.tables') 
SET @sqlCommand = REPLACE(@sqlCommand, '#name#', 'schema_info') 
SET @sqlCommand = REPLACE(@sqlCommand, '#what#', 'TABLE') 
EXEC (@sqlCommand) 
SET @sqlCommand = REPLACE(@sqlCommand, 'schema_info', 'scope_config') 
EXEC (@sqlCommand) 
SET @sqlCommand = REPLACE(@sqlCommand, 'scope_config', 'scope_info') 
EXEC (@sqlCommand) 

這一點,因爲你可以看到通過所有的表去,並試圖找到同步的痕跡。您只需更改數據庫名稱(第一行)。 另外,如果你想與你刪除的內容更安全,使用此代碼查找表:

-- get the next table 
    SELECT TOP 1 
     @id = object_id, 
     @name = REPLACE(name, '_tracking', '') 
    FROM sys.tables 
    WHERE object_id > @id 
    AND name LIKE '%_tracking' 
    ORDER BY object_id 

這隻會尋找那些實際上正在同步

0

你可以使用這個腳本表:

declare @SQL varchar(max); 
set @SQL=''; 
select @SQL += ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[schema_info]'') AND type in (N''U'')) ' + 
       ' DROP TABLE [dbo].[schema_info]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[scope_config]'') AND type in (N''U'')) ' + 
       ' DROP TABLE [dbo].[scope_config]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[scope_info]'') AND type in (N''U'')) ' + 
       ' DROP TABLE [dbo].[scope_info]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_tracking]'') AND type in (N''U'')) ' + 
       ' DROP TABLE [dbo].[' + name + '_tracking]; ' + 
       ' IF EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_delete_trigger]'')) ' + 
       ' DROP TRIGGER [dbo].[' + name + '_delete_trigger];' + 
       ' IF EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_insert_trigger]'')) ' + 
       ' DROP TRIGGER [dbo].[' + name + '_insert_trigger]; ' + 
       ' IF EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_update_trigger]'')) ' + 
       ' DROP TRIGGER [dbo].[' + name + '_update_trigger]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_delete]'') AND type in (N''P'', N''PC'')) ' + 
       ' DROP PROCEDURE [dbo].[' + name + '_delete]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_deletemetadata]'') AND type in (N''P'', N''PC'')) ' + 
       ' DROP PROCEDURE [dbo].[' + name + '_deletemetadata]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_insert]'') AND type in (N''P'', N''PC'')) ' + 
       ' DROP PROCEDURE [dbo].[' + name + '_insert]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_insertmetadata]'') AND type in (N''P'', N''PC'')) ' + 
       ' DROP PROCEDURE [dbo].[' + name + '_insertmetadata]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_selectchanges]'') AND type in (N''P'', N''PC'')) ' + 
       ' DROP PROCEDURE [dbo].[' + name + '_selectchanges]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_selectrow]'') AND type in (N''P'', N''PC'')) ' + 
       ' DROP PROCEDURE [dbo].[' + name + '_selectrow]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_update]'') AND type in (N''P'', N''PC'')) ' + 
       ' DROP PROCEDURE [dbo].[' + name + '_update]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_updatemetadata]'') AND type in (N''P'', N''PC'')) ' + 
       ' DROP PROCEDURE [dbo].[' + name + '_updatemetadata]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_BulkType]'') AND type in (N''P'', N''PC'')) ' + 
       ' DROP PROCEDURE [dbo].[' + name + '_BulkType]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_bulkinsert]'') AND type in (N''P'', N''PC'')) ' + 
       ' DROP PROCEDURE [dbo].[' + name + '_bulkinsert]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_bulkupdate]'') AND type in (N''P'', N''PC'')) ' + 
       ' DROP PROCEDURE [dbo].[' + name + '_bulkupdate]; ' + 
       ' IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[' + name + '_bulkdelete]'') AND type in (N''P'', N''PC'')) ' + 
       ' DROP PROCEDURE [dbo].[' + name + '_bulkdelete]; '    
from sysobjects 
where type = 'U' 

--select @SQL 
EXEC(@SQL) 
GO 
相關問題