2012-12-22 16 views

Odpowiedz

43

SQL - Linked Server

Jeśli oba serwery SQL Server można skonfigurować Linked servers - Chciałbym sugerują użycie konta SQL dla bezpieczeństwa.

Następnie można po prostu wykonać

insert into server2.database1.dbo.table1 
select * from server1.database1.dbo.table1 where col1 = 'X' 

Po uruchomieniu kwerendy w studiu zarządzania SQL podłączonego do server1 i aktualnej bazy danych ustawionym na database1, nie trzeba będzie prefiks

server1.database1.dbo. 

Ponadto serwer połączony byłby skonfigurowany na serwerze1, aby połączyć się z serwerem2 (a nie na odwrót).

Jeśli posiadasz poprawne sterowniki OLE DB, ta metoda może również działać między różnymi typami RDBMS (np. Inne niż SQL Server).

Otwarte Zapytanie

Uwaga: Uważać, aby nie polegać na połączonych serwerów zbyt dużo zwłaszcza dla filtrowania i łączy między serwerami, gdyż wymagają one dane należy czytać w całości na rzecz RDBMS pochodzących przed każdych warunkach można być stosowane. Wiele powikłań może powstać z serwerów połączonych, więc przeczytaj zanim wyjdziesz, ponieważ nawet różnice w wersjach mogą powodować bóle głowy.

Polecam użyć polecenia OPENQUERY dla serwerów SQL, aby ominąć takie ograniczenia.Oto przykład, ale należy znaleźć pomoc specyficzną dla swoich potrzeb poprzez dalsze badania:

insert into server2.database1.dbo.table1 
select * from OPENQUERY(server1, 'select * from database1.dbo.table1 where col1 = ''X'''); 

Powyższy kod jest bardziej wydajny, filtrowanie danych na serwerze źródłowym (i przy użyciu dostępnych indeksów), przed pompowaniem dane poprzez , oszczędzając przepustowość/czas/zasoby serwerów źródłowego i docelowego.

(także zwrócić uwagę na podwójny cudzysłów '', to sekwencja ucieczki, aby wytwarzać jeden cytat.)

SQL - Tymczasowo na tym samym serwerze

umożliwiłoby (uwaga podkreślenia):

insert into server2_database1.dbo.table1 
select * from database1.dbo.table1 

Wciąż w domenie zapytania SQL. Jeśli możesz tymczasowo przenieść bazę danych na serwerze2 do serwera1, nie będziesz potrzebował połączonego serwera. Zmiana nazwy bazy danych wydaje się być wymagana podczas wspólnego umieszczania na serwerze1. Osiągnięcie takich kolokacji może wykorzystać różne metody, proponuję kurczy plików bazy danych przed przystąpieniem albo:

  1. Kopia zapasowa/Przywracanie - backup na server2, przywracanie na server1 (z inną nazwą) - wykonać wkładkę, jak opisano powyżej , ale bez prefiksów serwer1 lub serwer2. Następnie odwróć - tworzenie kopii zapasowej na serwerze1, przywracanie na serwerze2/
  2. Odłącz/Dołącz - Zmień nazwę bazy danych, Odłącz na serwerze2, (kompresuj), skopiuj pliki na serwer 1, (rozpakuj), załącz na serwerze1, wykonaj wstawianie. Następnie odwróć ...

W obu przypadkach wersja serwera SQL może być barierą. Jeśli serwer1 ma niższą wersję SQL, wówczas zarówno metoda tworzenia kopii zapasowych, jak i odłączania/dołączania prawdopodobnie nie powiedzie się. Można to obejść, przenosząc bazę danych serwera1 do serwera2, która może być lub może nie być bardziej odpowiednia.

Inne sposoby

Może być korzystne, dla SQL/Sposób TSQL braku korzystne czynniki środowiskowe dla wcześniej wymienionych metod. A jeśli masz odpowiedni dostęp (sterowniki OLE DB itp.), Ta metoda może również działać między różnymi typami RDBMS (tj. Serwerami innego niż SQL Server) i źródłami danych (takimi jak XML, pliki płaskie, arkusze kalkulacyjne programu Excel). ...)

  • SSIS Jawnie z Business Development Management Studio - bezpośredni datapump lub stosując ograniczoną intermeditary pliku.
  • SSIS Niejawnie przez SQL Management Studio, klikając prawym przyciskiem myszy bazę danych1 na serwerze1> Zadania> Eksportuj, a następnie kończąc kreatora. Może pracować bezpośrednio na serwerze2 lub przy użyciu płaskiego pliku z pamięcią wewnętrzną.
  • Net Programowanie z SqlBulkInsert (wierzę datapump SSIS używa takiego obiektu), mogę przejść do bardziej szczegółowo na ten temat, jeśli cię to interesuje.

Np.SQLBulkInsert (psedo-C# code)

SqlConnection c = new SqlConnection("connectionStringForServer1Database1Here"); 
SqlConnection c2 = new SqlConnection("connectionStringForServer2Database1Here"); 
c.Open(); 
SqlCommand cm = new SqlCommand(c); 
cm.CommandText = "select * from table1;"; 
using (SqlDataReader reader = cm.ExecuteReader()) 
{ 
    using (SqlBulkInsert bc = new SqlBulkInsert(c)) 
    { 
     c2.Open(); 
     bc.DestinationTable = "table1"; 
     bc.WriteToServer(reader); 
    } 
} 

Całkiem fajnie, huh? Jeśli problemem jest szybkość/wydajność - podejścia oparte na SqlBulkInsert (takie jak SSIS) są najlepsze.

Update - Modyfikacja tabeli docelowej

Jeśli trzeba zaktualizować tabelę docelową, to polecam:

  1. Zapis do tabeli tymczasowej na docelowej bazy danych (tabela tymczasowa, lub właściwą tabelę, którą obcinacie przed i po procesie), to drugie jest lepsze. Ten pierwszy może być twoim jedynym wyborem, jeśli nie masz uprawnień do tworzenia tabeli. Możesz wykonać przelew korzystając z jednej z powyższych opcji.
  2. Uruchom polecenie MERGE INTO zgodnie z wymaganiami z tabeli pomostowej do tabeli docelowej. Może to bardzo wydajnie wstawiać, aktualizować i usuwać według potrzeb.

Taki cały proces może zostać zwiększona z oknem przesuwnym (zmiany od ostatniego sprawdzenia), tylko biorąc zmienili wierszy w źródle zastosowanie do miejsca przeznaczenia, to komplikuje proces, więc należy przynajmniej osiągnąć prostszy pierwszy. Po ukończeniu przesuwanej wersji okna można okresowo uruchamiać pełną aktualizację, aby upewnić się, że nie ma błędów w przesuwanym oknie.

+1

Dziękujemy za zgłoszenie problemu z ŁĄCZENIE na serwerach powiązanych. Nawet jeśli nie są używane w DOŁĄCZYCH, nadal występują problemy z DML na połączonych serwerach, które mogą naprawdę spowolnić działanie. +1. Ponadto, jeśli chodzi o użycie 'SqlBulkInsert' poprzez SQLCLR, jeśli ktoś chce to zrobić, ale nie wie, jak to zrobić lub po prostu nie chce spędzać czasu na nim, dostępna jest bezpłatna wersja [SQL #] (http : //www.SQLsharp.com/) biblioteka (której jestem autorem) zawiera procedurę przechowywaną, ** DB_BulkCopy **, która to robi i eksponuje większość opcji (np.BulkCopyOptions, mapowanie kolumn, wielkość partii itp.). –

+1

@ srutzky Chciałbym użyć funkcji importu/eksportu programu SQL Server Managment Studio do jednorazowych zadań, a przy każdej edycji większej niż Express można zapisać te procesy jako skrypty SSIS do edycji/ponownego użycia. SQL # wygląda na przydatny, wypróbuję go pewnego dnia. – Todd

8

do kopiowania danych pomiędzy dwoma różnymi serwerami masz kilka opcji:

+0

Nie chciałam kolejność, wiem, że jest 'wstawić [,,,] ... wybierz [,,,] z ...' To znaczy, jak skopiować dane między dwoma serwery. –

+0

@mahditahsildari: Możesz używać połączonych serwerów. –

1

Najlepszym sposobem na to byłoby stworzenie "połączonego serwera". a następnie można skorzystać z poniższego oświadczenia do wyciągu wkładki w celu zdefiniowania tabela

[linkedserver].databasename.dbo.tablename 
3

podobne do Todd C# SqlBulkCopy

Generalnie jest to łatwiejsze niż tworzenie połączonych serwerów.

Utwórz test jednostki i wykonaj poniższe czynności, jeśli masz wyzwalacze, a następnie zachowaj ostrożność i będziesz potrzebować uprawnień ALTER.

[Test] 
    public void BulkCopy() 
    { 
     var fromConnectionString = @"fromConnectionString"; 
     var destinationConnectionString = @"destConnectionString2"; 

     using (var testConnection = new SqlConnection(fromConnectionString)) 
     { 
      testConnection.Open(); 
      var command = new SqlCommand("select * from MyTable;", testConnection); 
      using (var reader = command.ExecuteReader()) 
      { 
       using (var destinationConnection = new SqlConnection(destinationConnectionString)) 
       { 
        using (var bc = new SqlBulkCopy(destinationConnection)) 
        { 
         destinationConnection.Open(); 
         bc.DestinationTableName = "dbo.MyTable"; 
         bc.WriteToServer(reader); 
        } 
       } 
      } 
     } 
    } 
} 
0

Najpierw należy dodać serwer Np. Serwer 1 i serwer 2

sp_addlinkedserver 'Server-2'

następnie skopiować dane z tego serwera do serwera za pomocą następującego zapytania

serwer-1 Napisz

select * INTO Employee_Master_bkp 
FROM [Server-2].[DB_Live].[dbo].[Employee_Master] 
0

Jeśli potrzebujesz alternatywę bez przy użyciu serwerów połączonych, moją ulubioną opcją jest użycie narzędzia BCP wiersza poleceń. Za pomocą tego narzędzia do kopiowania zbiorczego można wyeksportować dane do płaskiego pliku, skopiować plik przez sieć i zaimportować go (załadować) na serwer docelowy.

https://docs.microsoft.com/en-us/sql/tools/bcp-utility

Powiązane problemy