20. juni 2007 - 09:47Der 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.
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.
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...
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.
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
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>")
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?
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.
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.
Synes godt om
Ny brugerNybegynder
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.