2015-06-16 5 views
3

У меня есть две разные базы данных, один из которых подключен от файла .MDF к серверу .\SQLEXPRESS. Мастер-сервер работает на сервере на другом компьютере под названием COMPUTER_NAME.Как объединить две базы данных на двух разных серверах?

Я хочу объединить их с помощью C# для запуска файла .SQL. Я вставить свой код ниже для справки, но в основном моя проблема заключается в том, что если я подключиться к серверу с помощью

string sqlConnectionString = @"Server=.\SQLEXPRESS; Trusted_Connection=True"; 

Тогда я не могу найти базу данных на COMPUTER_NAME. И если я использую

string sqlConnectionString = @"Server=COMPUTER_NAME; Trusted_Connection=True"; 

Это будет выглядеть мой .MDF файл на C: привод COMPUTER_NAME, а не на локальной машине.

Как подключиться к обеим этим базам данных на разных серверах?

Дополнительная информация:

SQL-скрипт я использую. Это отлично отработало, когда обе базы данных были на одном сервере, но я больше не могу этого делать.

CREATE DATABASE ClientDB 
ON (Filename = 'C:\Clayton.mdf') 
    , (Filename = 'C:\Clayton_log.ldf') 
FOR ATTACH; 

-- update the client from the master 
MERGE [ClientDB].[dbo].[table] trgt 
using [MasterDB].[dbo].[table] src 
ON trgt.id = src.id 

WHEN matched AND trgt.lastmodified <= src.lastmodified THEN -- if master row is newer 
    UPDATE SET trgt.[info] = src.[info], ...     -- update the client 

WHEN NOT matched BY source         -- delete rows added by client 
    THEN DELETE 

WHEN NOT matched BY target         -- insert rows added by master 
    THEN INSERT ([info], ...) VALUES (src.[info], ...); 


-- close all connections to database 
ALTER DATABASE ClientDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE; 

-- detach database 
EXEC sp_detach_db 'ClientDB', 'true'; 

И я бегу это с помощью C#, как так:

string sqlConnectionString = @"Server=.\SQLEXPRESS; Trusted_Connection=True"; 

string script = File.ReadAllText(Environment.CurrentDirectory + @"\MergeTotal.sql"); 
SqlConnection conn = new SqlConnection(sqlConnectionString); 

IEnumerable<string> commandStrings = Regex.Split(script, @"^\s*GO\s*$", 
          RegexOptions.Multiline | RegexOptions.IgnoreCase); 

conn.Open(); 
foreach (string commandString in commandStrings) 
{ 
    if (commandString.Trim() != "") 
    { 
     using (var command = new SqlCommand(commandString, conn)) 
     { 
      command.ExecuteNonQuery(); 
     } 
    } 
} 

Я не волнует, если весь процесс происходит в .SQL или в C# так долго, как это имеет желаемый эффект.

Заранее благодарим за любые рекомендации или рекомендации.

+0

Как часто вам нужно запустить это? –

+0

Часто я боюсь. Сейчас он настроен так, что каждый раз, когда запускается программа, он проверяет, подключен ли он к сети с основной базой данных и будет сливаться, если это так. –

+0

Возможно, вам придется рассмотреть редизайн того, как он работает, так как вы не можете так слиться. Вероятно, вы должны отслеживать изменения, а затем повторно использовать их на главном сервере. –

ответ

2

Ссылка на серверы поможет вам получить доступ к данным одновременно, если это необходимо. Если вы хотите объединить данные вместе, я бы предложил вам проверить sp_generate_merge, чтобы вытащить данные в скрипт слияния для вас (очень удобно для перемещения данных). См. Также мой вопрос о генерации данных слияния here.

+0

Спасибо за ваш ответ! Можете ли вы привести мне пример того, как я буду использовать это в этой ситуации? Мне нужно объединить оба способа для фиксации изменений обеих версий, но я продолжаю получать ошибку «цель оператора MERGE не может быть удаленной таблицей». –

+0

Вам нужно сгенерировать скрипт слияния на одной машине, скопировать вывод и запустить слияние на другой машине. Затем вы измените процесс. –

0

Хорошо, мне пришлось полностью выкинуть всю вещь .MDF. Вместо привязки и повторной привязки базы данных от .MDF я просто создал базу данных.

Вот мой код, чтобы инициализировать локальную базу данных на планшете:

CREATE DATABASE LocalClaytonDB 
ON (Filename = 'C:\ProgramData\Clayton\Clayton.mdf') 
    , (Filename = 'C:\ProgramData\Clayton\Clayton_log.ldf') 
FOR ATTACH; 
GO 

EXEC sp_addlinkedserver @server='Server' 

Вот мой код, чтобы синхронизировать две базы данных:

-- update the client from the master 
MERGE [LocalClaytonDB].[dbo].[tableName] trgt 
using [Server].[Clayton].[dbo].[tableName] src 

ON trgt.id = src.id 

WHEN matched AND trgt.lastmodified <= src.lastmodified THEN 
    -- if the master has a row newer than the client 
    -- update the client      
    UPDATE SET trgt.[allColumns]  = src.[allColumns], 
      trgt.[id]    = src.[id], 
      trgt.[lastmodified] = src.[lastmodified] 

-- delete any rows added by a client 
WHEN NOT matched BY source 
THEN 
    DELETE 

-- insert any rows added by the master 
WHEN NOT matched BY target 
THEN 
    INSERT ([allColumns], 
      [id], 
      [lastmodified]) 
    VALUES (src. [allColumns], 
      src.[id], 
      src.[lastmodified]); 


-- now we update the master from the client 
-- Note: 
-- because the serverDB is a linked server 
-- we can't use another MERGE statement, otherwise 
-- we get the error: "The target of a MERGE statement 
-- cannot be a remote table, a remote view, or a view over remote tables." 

UPDATE 
    serverDB 

SET 
    [allColumns]  = [localDB].[allColumns], 
    [id]    = [localDB].[id], 
    [lastmodified]  = [localDB].[lastmodified] 

FROM 
    [Server].[Clayton].[dbo].[tableName] serverDB 

INNER JOIN 
    [LocalClaytonDB].[dbo].[tableName] localDB 

-- update where the id is the same but the client is newer than the master 

ON serverDB.id = localDB.id 
     AND localDB.lastmodified >= serverDB.lastmodified 
Смежные вопросы