Avatar billede angelenglen Nybegynder
20. juni 2007 - 09:47 Der er 11 kommentarer og
2 løsninger

Synkroniser tabeller mellem to MS SQL servere

Jeg har to MS SQL 2005 Standard Edition servere kørende,
1 i drift, 1 i udvikling

Jeg vil så gerne kunne synkronisere alle eller udvalgte tabeller i en database, således at ændringer lavet i udviklings-databasens tabeller (både struktur og data) bliver pushet op i drifts-databasen, men uden at denne ryger offline (ihvertfald ikke i mere end kort tid!)

Findes der evt. 3.parts applikationer til dette, eller kan jeg mon scripte mig ud af det, eksempelvis via asp?

(Jeg er relativt ny indenfor MS SQL, jeg er vant til andre databaser)

Ved flere brugbare svar, vil points blive fordelt.
Avatar billede terry Ekspert
20. juni 2007 - 09:50 #1
Avatar billede angelenglen Nybegynder
20. juni 2007 - 10:03 #2
Hmm jeg skulle måske have nævnt at jeg foretrækker gratis produkter.

Du får stadig nogle points når jeg lukker spørgsmålet, for dit svar ser ud til at kunne løse problemet, men jeg vil lige vente lidt, i håb om at der kommer nogle løsninger der ikke koster $295.
Avatar billede teepee Nybegynder
20. juni 2007 - 10:22 #3
Sådan set skal du jo bare lave to kørsler for hver tabel (kræver database link mellem baserne)
Update prodtabel1 pt1
set (kol2,kol3,kol4,kol5) = (select kol2, kol3,kol4, kol5
                              from udvtabel1 ut1
                            where ut1.kol1 = pt1.kol1);

insert into prodtabel1 (kol1, kol2, kol3, kol4, kol5)
select kol1,kol2,kol3,kol4,kol5
from udvtabel1 ut1
where not exists (select kol1
                  from prodtabel1 pt2
                  where pt2.kol1 = ut1.kol1);

Betinget af at kol1 er en primærnøgle... Du kommer dog hurtigt til at bruge for langt mere end kr. 1500,- i tid på at lave det hele selv...
Avatar billede angelenglen Nybegynder
20. juni 2007 - 11:34 #4
det ser umiddelbart spænnende ud det script, men vil den ikke blot kopiere data, og ikke opdatere strukturen? (hvis der fx er tilføjet et ekstra felt, eller fjernet et, i udv.databasen)

-og kan det ikke lade sig gøre at lave felt-navnene dynamiske? -det ville være irriterende at skulle rette scriptet hver gang man ændrer i feltnavne eller tilføjer/fjerner et felt.
Avatar billede angelenglen Nybegynder
14. september 2009 - 09:53 #5
Det er vist på høje tid at få lukket her.
Jeg deler bare points mellem alle svar.
Avatar billede terry Ekspert
14. september 2009 - 10:03 #6
tak
Avatar billede fischer Nybegynder
11. december 2009 - 12:35 #7
Fandt du ud af om det kunne gøres dynamisk? Jeg sidder med samme opgave her :-)

-K
Avatar billede angelenglen Nybegynder
12. december 2009 - 23:11 #8
Det er efterhånden et par år siden, men jeg fik aldrig løst problemet.
Men relativt kort efter blev projektet jeg arbejdede på droppet, hvilket er en del af grunden til jeg aldrig kom videre i jagten på en løsning.

Havde det været kopi af en tabel til en anden, på samme server, kunne det dog let scriptes, ved jeg nu.

Følgende er et eksempel på et vbscript der kopierer alle tabeller fra én database til en anden.
Der er dog også lidt med at den omdøber tabellerne undervejs, men det er fordi formålet med dette script er en slags backup, op til 7 dage tilbage, men det kan være det kan give dig lidt inspiration til at komme videre?

Gem fx scriptet i filen "test.vbs" og kør kommandoen "cscript test.vbs" fra en command-prompt.








on error resume next 'enable error-handling before running script...
BackupDatabase "production_db" 'lav backup af production database
BackupDatabase "development_db" 'lav backup af development database
on error goto 0 'disable error-handling again...

' ## Dette script går ud fra at hvis der laves backup af database ved navn "test", så findes der en database ved navn "test_backup" som tabellerne kan kopieres over i.
' ## Kort fortalt, den database der laves kopi af, kopieres over i database ved samme navn men _backup efter.


Function BackupDatabase(DbNavn)
    WScript.Echo vbcrlf & "Initializing back up of database: " & DbNavn & "."
    Set Conn = CreateObject("ADODB.Connection")
    Conn.Open "DSN=" & DbNavn & "_dsn;UID=backup_user;PWD=p@ssw0rd"
    'få en liste over alle tabeller:
    SQL = "SELECT table_name FROM " & DbNavn & ".INFORMATION_SCHEMA.Tables WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY table_name ASC"
    Set rsTables = Conn.Execute(SQL)   
    If Err.Number <> 0 Then
        WScript.Echo vbcrlf & "Error backing up database: " & DbNavn & " - Description: " & err.Description & vbcrlf & "Failed query: " & SQL & vbcrlf & vbcrlf
        Err.Clear
    end if
   
    'Find dagens navn (mon = mandag ... sun = søndag)
    UgeDage = Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat") 'bruger engelske dage for at undgå æøå
    DagNavn = UgeDage(WeekDay(Now()) - 1) 'minus en, fordi i USA starter ugen åbenbart om søndagen?!
   
    'Kopier alle tabeller til backup-databasen, prefixed med dagens navn, eksempelvis tabel Brugere kopieres til wed_brugere hvis det er onsdag.
    'Tabellerne prefixes med dagen dels for at holde hvert "sæt" tabeller samlet, dels for at have op til en uges backup.
    failed = 0
    counter = 0
    Do while not (rsTables.eof or rsTables.bof)
        OrgNavn = rsTables("table_name")
        KopiNavn = DagNavn & "_" & rsTables("table_name")
        'slet backup-tabellen først hvis den eksisterer, der kan ikke bare opdateres eller overskrives...
            CopySQL = "IF EXISTS(SELECT table_name FROM " & DbNavn & "_backup.INFORMATION_SCHEMA.Tables WHERE table_name = '" & KopiNavn & "') DROP TABLE " & DbNavn & "_backup.dbo." & KopiNavn & ";"
            CopySQL = CopySQL & "SELECT * INTO " & DbNavn & "_backup.dbo." & KopiNavn & " FROM " & DbNavn & ".dbo." & OrgNavn
            Conn.Execute(CopySQL)
            If Err.Number <> 0 Then
                failed = failed + 1
                failed_tables = failed_tables & OrgNavn & ", "
                WScript.Echo vbcrlf & "Error backing up " & OrgNavn & " - Description: " & err.Description & vbcrlf & "Failed query: " & CopySQL & vbcrlf & vbcrlf
                Err.Clear
            else
                counter = counter + 1
                ok_tables = ok_tables & OrgNavn & ", "
                Err.Clear
            end if
    rsTables.MoveNext
    Loop

    if failed_tables <> "" then failed_tables = left(failed_tables,len(failed_tables) - 2) 'fjern det sidste ", "
    if ok_tables <> "" then ok_tables = left(ok_tables,len(ok_tables) - 2) 'fjern det sidste ", "

    WScript.Echo "Backed up database: " & DbNavn & "."
    if counter > 0 then WScript.Echo "Successful tables: " & counter & " (" & ok_tables & ")."
    if failed > 0 then WScript.Echo "Failed tables: " & failed & " ( " & failed_tables & " )."

    Set Conn = nothing 'luk db-forbindelse
End Function
Avatar billede fischer Nybegynder
14. december 2009 - 12:25 #9
Hep hey, tusind tak for den.
Jeg har sat det op i et ASP-script til en "linked" database, så virker det fra én server til en anden :-)

-Klaus
For de nysgerrige er koden:

  DbNavn = "DKD" 'lokal
  DKDOnline = "DbOnline.databasenavn" 'navn på linked databaseserver.databasenavn
 
  Set Conn = CreateObject("ADODB.Connection")
  Conn.Open("Provider=SQLOLEDB.1;Data Source=klausPD\SQLExpress;uid=XXX;pwd=XXX;Database="& DbNavn &"")

  'få en liste over alle tabeller:
  SQL = "SELECT table_name FROM " & DKDOnline & ".INFORMATION_SCHEMA.Tables WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY table_name ASC"
  response.write(SQL &"<br>")
  Set rsTables = Conn.Execute(SQL)
  If Err.Number <> 0 Then
      Response.write( vbcrlf & "Error backing up database: " & DbNavn & " - Description: " & err.Description & vbcrlf & "Failed query: " & SQL & vbcrlf & vbcrlf)
      Err.Clear
  end if
 
  'Kopier alle tabeller til backup-databasen
  failed = 0
  counter = 0
  Do while not (rsTables.eof or rsTables.bof)
      'slet backup-tabellen først hvis den eksisterer, der kan ikke bare opdateres eller overskrives...
          CopySQL = "IF EXISTS(SELECT table_name FROM " & DbNavn & ".INFORMATION_SCHEMA.Tables WHERE table_name = '" & rsTables("table_name") & "') DROP TABLE " & DbNavn & ".dbo." & rsTables("table_name") & ";"
          CopySQL = CopySQL & "SELECT * INTO " & DbNavn & ".dbo." & rsTables("table_name") & " FROM " & DKDonline & ".dbo." & rsTables("table_name")
          Conn.Execute(CopySQL)
          If Err.Number <> 0 Then
              failed = failed + 1
              failed_tables = failed_tables & rsTables("table_name") & ", "
              response.write( vbcrlf & "Error backing up " & rsTables("table_name") & " - Description: " & err.Description & vbcrlf & "Failed query: " & CopySQL & vbcrlf & vbcrlf)
              Err.Clear
          else
              counter = counter + 1
              ok_tables = ok_tables & rsTables("table_name") & ", "
              Err.Clear
          end if
  rsTables.MoveNext
  Loop

  if failed_tables <> "" then failed_tables = left(failed_tables,len(failed_tables) - 2) 'fjern det sidste ", "
  if ok_tables <> "" then ok_tables = left(ok_tables,len(ok_tables) - 2) 'fjern det sidste ", "

  Response.write("<br><br>Backed up database: " & DbNavn & ".<br>")
  if counter > 0 then response.write("Successful tables: " & counter & " (" & ok_tables & ").<br>")
  if failed > 0 then response.write("Failed tables: " & failed & " ( " & failed_tables & " ).<br>")

  Set Conn = nothing 'luk db-forbindelse
Avatar billede angelenglen Nybegynder
14. december 2009 - 12:33 #10
Super, glad for at kunne hjælpe :-)
Avatar billede fischer Nybegynder
16. december 2009 - 10:54 #11
Ja ja, OK, det virker så kun "næsten". Man får ikke primary keys, identity-indstillinger og default-værdier med over kan jeg se.
Nogen der har et forslag til at få det med i en SQL-streng?

-Klaus
Avatar billede angelenglen Nybegynder
16. december 2009 - 11:03 #12
Nårh ja, det vidste jeg faktisk godt.
Det er bare så længe siden jeg har brugt scriptet, at jeg glemte den detalje :-(

I sin tid da jeg brugte scriptet, var det dog vigtigst for mig at have de data der var i tabellerne, ikke så meget tabellernes indstillinger, hvorfor det ikke var vigtigt for mig at løse dét problem.
Avatar billede angelenglen Nybegynder
16. december 2009 - 11:04 #13
Du bliver muligvis nød til at oprette et nyt spørgsmål, for at få hjælp til dit problem.
Men hvis du finder en løsning, må du da meget gerne linke til den her bagefter.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester