Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

MS SQL 2005er Express - Update einer Tabelle aus 2. DB

Frage Entwicklung Datenbanken

Mitglied: Iwan

Iwan (Level 2) - Jetzt verbinden

28.11.2011, aktualisiert 12:21 Uhr, 4228 Aufrufe, 11 Kommentare

Guten morgen zusammen,

ich habe 2 Datenbanken, die beide die gleiche Tabelle "Datentab" (13 Spalten) enthalten.
Die Tabelle in DB1 enthält diverse Daten, die Tabelle in DB2 ist leer.
Nun möchte ich die Tabelle in DB2 mit Daten aus DB1 füllen.
Allerdings soll hier ein Kriterium (ArtNr=4712) berücksichtigt werden.

Die Selektion der Daten in DB1 ist kein Problem:
01.
SECLECT * FROM Datentab 
02.
WHERE ArtNr=4712
aber wie kriege ich das Ergebnis nun in DB2 rein?

Bei einer geringen Zeilenanzahl habe ich das ganze bisher mit Copy&Paste gemacht.
Das ist allerdings bei den heutigen Datenmenge kaum noch machbar oder dauert ewig.

Hat hier jemand einen Tip für mich?

Ja, ich habe Google schon befragt, aber komme da nicht weiter.
Nein, ich möchte keine zusätzlichen Programme oder Tools verwenden.
Tablediff.exe habe ich schon probiert, aber ist mir zu "unhandlich".


*nachtrag*
Ich habe doch noch was rausgefunden (beide DB_Server sind verbunden):
01.
INSERT INTO DB2.Daten.dbo.Datentab SELECT  ArtNr, Beschr, Preis FROM DB1.Daten.dbo.Datentab WHERE ArtNr=4712
Das schmeisst mir aber einen Fehler raus:
01.
Meldung 7202, Ebene 11, Status 2, Zeile 1 
02.
Der Server 'DB1' wurde in sys.servers nicht gefunden. Prüfen Sie, ob der richtige Servername angegeben wurde. Führen Sie bei Bedarf die gespeicherte Prozedur sp_addlinkedserver aus, um den Server zu sys.servers hinzuzufügen.
Mitglied: Indrador
28.11.2011 um 12:27 Uhr
Guten Tag,

also deine Datenbanken liegen auf 2 verschiedenen Servern, hast du denn auf dem Server, auf dem die Abfrage läuft auch den anderen Server als Linkserver eingerichtet?
Lauf Fehlermeldung scheinbar nicht, also erstmal Linkserver anlegen:

01.
EXEC master.dbo.sp_addlinkedserver @server = N'DB1', @srvproduct=N'SQL Server' 
02.
GO 
03.
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'DB1',@useself=N'False',@locallogin=NULL,@rmtuser=N'USERNAME',@rmtpassword='PASSWORT' 
04.
GO 
05.
EXEC master.dbo.sp_serveroption @server=N'DB1', @optname=N'collation compatible', @optvalue=N'false' 
06.
GO 
07.
EXEC master.dbo.sp_serveroption @server=N'DB1', @optname=N'data access', @optvalue=N'true' 
08.
GO 
09.
EXEC master.dbo.sp_serveroption @server=N'DB1', @optname=N'dist', @optvalue=N'false' 
10.
GO 
11.
EXEC master.dbo.sp_serveroption @server=N'DB1', @optname=N'pub', @optvalue=N'false' 
12.
GO 
13.
EXEC master.dbo.sp_serveroption @server=N'DB1', @optname=N'rpc', @optvalue=N'false' 
14.
GO 
15.
EXEC master.dbo.sp_serveroption @server=N'DB1', @optname=N'rpc out', @optvalue=N'false' 
16.
GO 
17.
EXEC master.dbo.sp_serveroption @server=N'DB1', @optname=N'sub', @optvalue=N'false' 
18.
GO 
19.
EXEC master.dbo.sp_serveroption @server=N'DB1', @optname=N'connect timeout', @optvalue=N'0' 
20.
GO 
21.
EXEC master.dbo.sp_serveroption @server=N'DB1', @optname=N'collation name', @optvalue=null 
22.
GO 
23.
EXEC master.dbo.sp_serveroption @server=N'DB1', @optname=N'lazy schema validation', @optvalue=N'false' 
24.
GO 
25.
EXEC master.dbo.sp_serveroption @server=N'DB1', @optname=N'query timeout', @optvalue=N'0' 
26.
GO 
27.
EXEC master.dbo.sp_serveroption @server=N'DB1', @optname=N'use remote collation', @optvalue=N'true' 
28.
GO
Du musst @server=N'DB1', überall mit dem richtigen Hostnamen ersetzen UND
@rmtuser=N'USERNAME',@rmtpassword='PASSWORT' mit dem richtigen Usernamen und Passwort.


Wenn das der Fall ist und der Server angelegt ist, geht der Insert so:
01.
-- Abfrage auf DB2 ausführen 
02.
-- Das InsertStatement zeigt auf DB2 
03.
INSERT INTO Daten.dbo.Datentab (Feld1, Feld2) 
04.
-- Der Openquery Select zeigt auf DB1 
05.
SELECT * from OPENQUERY (LINKSERVERNAME, 'select Feld1, Feld2 from Daten.dbo.Datentab WHERE ArtNr=4712 with (nolock)')
Bitte warten ..
Mitglied: Iwan
28.11.2011 um 13:11 Uhr
Vielen dank, das mit dem registrieren hatte ich schon versucht und er tauchte auch unter 'Registrierte Server' auf.
Allerdings brachte die Abfrage
01.
SELECT * FROM sys.servers
immer nur den lokalen Server.
Dann habe ich es per 'sp_addlinkedserver' versucht, aber wohl nicht die richtigen Befehle oder Werte genommen.
Nun habe ich es so gemacht, wie du beschrieben hast, und nun geht auch der Datentransfer.

Nochmals vielen dank!


Gäbe es damit eigentlich auch die Möglichkeit, nur fehlende Einträge zu ergänzen oder sogar vorhandene zu aktualisieren?
Beim Insert werden nämlich Pirmary Keys verletzt.
Bitte warten ..
Mitglied: Indrador
28.11.2011 um 17:08 Uhr
Hi, mir fallen spontan zwei Möglichkeiten ein:

MÖGLICHKEIT 1:

Die sp_addlinkedserver auf dem DB1 ausführen mit Daten von DB2, nun kennst du DB2 auf DB1 und auf DB1 kennst du DB2.

hier machst du nun folgedes auf dem Server, der die fehlenden Daten hat (DB1):
01.
Create View v_Differenz_DB1_zu_DB2 
02.
AS 
03.
Select Feld1, Feld2, .... from Daten.dbo.Datentab where PK not in ( 
04.
SELECT * from OPENQUERY (DB2, 'select PK from Daten.dbo.Datentab with (nolock)') 
05.
Go
nun hast du auf DB1 eine View, in der nur Datensätze sind, die es auf DB2 nicht gibt.


Dann ersetzt du in dem Insert Schnipselchen von Oben
01.
SELECT * from OPENQUERY (LINKSERVERNAME, 'select Feld1, Feld2 from Daten.dbo.Datentab WHERE ArtNr=4712 with (nolock)')
mit
01.
SELECT * from OPENQUERY (LINKSERVERNAME, 'select Feld1, Feld2 from Daten.dbo.v_Differenz_DB1_zu_DB2')
MÖGLICHKEIT 2:

auf DB2 folgendes:

01.
Create View v_Datenbestand_DB1 
02.
AS 
03.
SELECT * from OPENQUERY (DB1, 'select * from Daten.dbo.Datentab with (nolock)' 
04.
GO
01.
INSERT INTO Daten.dbo.Datentab  
02.
SELECT  ArtNr, Beschr, Preis FROM Daten.dbo.v_Datenbestand_DB1 WHERE Artnr not in (Select Artnr from Daten.dbo.Datentab (nolock))
Ich kann grade nichts testen, bin unterwegs, falls irgendwelche Fehler geworfen werden, meld dich einfach nochmal mit kompletter Meldung.
Gruß
Bitte warten ..
Mitglied: Iwan
29.11.2011 um 09:54 Uhr
Guten morgen,

ich bevorzuge Möglichkeit 2, da ich dies dann auf jedem x-beliebigem Rechner machen kann.
Dazu muss ich dann nur auf dem Zielrechner die Quelle registrieren.

Nur noch mal zur Sicherheit:
DB1 = Quelle, DB2 = Ziel

Ich habe das mit dem "Create View" auf DB2 in einem SQL-Query ausprobiert.
Erst erhielt ich eine Fehlermeldung, aber da fehlt am Ende von Zeile 3 eine Klammer.

1. bei einem zweiten Aufruf erhalte ich die Meldung, das 'v_Datenbestand_DB1' schon existiert
Wie kann ich die zunächst löschen (per Skript, nicht manuell), damit sie mit jedem Aufruf neu erstellt wird?

2. wie kann ich den Filter auf ArtNr=4711 einbauen?
Ich habe Zeile 3 entsprechend erweitert:
01.
SELECT * from OPENQUERY (DB1, 'select * from Daten.dbo.Datentab with (nolock) where ArtNr=4711' 
In der v_Datenbestand_DB1 stehen dann auch nur die selektierten, aber es erfolgt dann Abgleich mehr mit der Zieltabelle.
Zumindest schreibt er die fehlenden Einträge nicht rein.
Ich vermute mal, das es an der schon vorhandenen ArtNr liegt, denn wenn ich als Kriterium im 2. Teil 2. Zeile statt ArtNr mal Preis ausgewählt habe, dann funktioniert es.
Ist aber kein Problem, wenn man es weiß, nur so bekomme ich halt kein Update auf vorhandene Sätze.
Dann lösch ich halt vorhandene vorher und gut ist's.
Bitte warten ..
Mitglied: Indrador
29.11.2011 um 10:48 Uhr
Zitat von Iwan:
Nur noch mal zur Sicherheit:
DB1 = Quelle, DB2 = Ziel

Ja so soll es sein, DB1 ist die Quelle des Vergleichs, weil da gibt es mehr Daten.

Ich habe das mit dem "Create View" auf DB2 in einem SQL-Query ausprobiert.
Erst erhielt ich eine Fehlermeldung, aber da fehlt am Ende von Zeile 3 eine Klammer.

Welch eine Nachlässigkeit von mir, war aber wie gesagt unterwegs =)

1. bei einem zweiten Aufruf erhalte ich die Meldung, das 'v_Datenbestand_DB1' schon existiert
Wie kann ich die zunächst löschen (per Skript, nicht manuell), damit sie mit jedem Aufruf neu erstellt wird?

01.
IF  EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[v_Datenbestand_DB1]')) 
02.
DROP VIEW [dbo].[v_Datenbestand_DB1] 
03.
GO
Über das Create view, allerdings weiß ich nicht, warum du die view jedes mal neu erstellen willst/musst, sie liefert immer ein dynamisches Ergebnis.
Stell dir das so vor, du führst

01.
Select Feld1, Feld2, .... from Daten.dbo.Datentab where PK not in ( SELECT * from OPENQUERY (DB2, 'select PK from Daten.dbo.Datentab with (nolock)')
aus dem Management Studio mit F5 aus und erhälst 2 Datensätze. Diese zwei fügst du nun in deine zweite Tabelle ein und drückst wieder F5 nun erhälst du nichts mehr.
In der View passiert das gleiche, wenn du Sie aufrust, kriegst du 2 Datensätze, nach dem Insert 0.
Eine View ist praktisch sowas wie eine gewisse Query statisch anlegen und in der View ist immer das Ergebnis der Query zur Laufzeit.

Wenn das nicht verständlich ist, meld dich noch mal dazu.


2. wie kann ich den Filter auf ArtNr=4711 einbauen?
Ich habe Zeile 3 entsprechend erweitert:
01.
SELECT * from OPENQUERY (DB1, 'select * from Daten.dbo.Datentab with (nolock) where ArtNr=4711' 
02.
> 
In der v_Datenbestand_DB1 stehen dann auch nur die selektierten, aber es erfolgt dann Abgleich mehr mit der Zieltabelle.
Zumindest schreibt er die fehlenden Einträge nicht rein.
Ich vermute mal, das es an der schon vorhandenen ArtNr liegt, denn wenn ich als Kriterium im 2. Teil 2. Zeile statt ArtNr mal
Preis ausgewählt habe, dann funktioniert es.
Ist aber kein Problem, wenn man es weiß, nur so bekomme ich halt kein Update auf vorhandene Sätze.
Dann lösch ich halt vorhandene vorher und gut ist's.

Hier kann ich dir ehrlich gesagt jetzt grade nur helfen, wenn du mir einmal den Aufbau von DB1..Tabelle und DB2..Tabelle
beschreibst und auf welchen Spalten die einzufügenden Differenzen sind. Die Abfrage dann zu finden ist kein Problem.
Bitte warten ..
Mitglied: Iwan
29.11.2011 um 12:36 Uhr
Ich hatte es mit DELETE probiert, weil ich DROP noch nicht kannte, aber man lernt nie aus

Das mit dem Löschen bevor ich die Daten neu einlese, ist kein Problem.
Daher ist mir das Aktualisieren der Daten jetzt nicht so wichtig.
Die beiden Tabellen sind wie folgt aufgebaut:
ArtNr (4-stellige Zahl), KdKreis (2-stellige Zahl), Beschr (Text), Preis (Zahl)
Vergleichswerte wäre in dem Fall z.Bsp. der KdKreis, wo dann die Beschr und der Preis aktualisiert werden müssten.
Der Artikel wäre dann ja schon vordefiniert bzw. gefiltert (4711).
Bitte warten ..
Mitglied: Indrador
29.11.2011 um 14:55 Uhr
Zitat von Iwan:
Das mit dem Löschen bevor ich die Daten neu einlese, ist kein Problem.
Daher ist mir das Aktualisieren der Daten jetzt nicht so wichtig.

Jetzt müssen wir noch einmal begriffe abgrenzen:
Reden vir von anfügen oder aktualisieren?

Anfügen wäre in Tabelle2 gibt es Datensatz X nicht, aktualisieren wäre in Tabelle2 Gibt es
Datensatz X und im Feld muss nun der Wert Y statt Z stehen.

Beispiel für Anfügen (Datensatz von Kunde 113 fehlt noch komplett in Tabelle 2 und muss da rein):
Tabelle DB1
01.
Artikel		Kunde		Preis 
02.
4711		111			5,00 
03.
4711		112			7,00 
04.
4711		113			8,00
Tabelle DB2
01.
Artikel		Kunde		Preis 
02.
4712		111			5,00 
03.
4713		112			7,00
Beispiel für aktualisieren (Kunde 113 der Preis muss in Tabelle 2 auch auf 1,00):
Tabelle DB1
01.
Artikel		Kunde		Preis 
02.
4711		111			5,00 
03.
4711		112			7,00 
04.
4711		113			1,00
Tabelle DB2
01.
Artikel		Kunde		Preis 
02.
4711		111			5,00 
03.
4711		112			7,00 
04.
4711		113			8,00
Gruß
Bitte warten ..
Mitglied: Iwan
29.11.2011 um 15:33 Uhr
Sowohl als auch:
- es kann sein, das ein neuer Datensatz in DB1 steht, aber nicht in DB2
- es kann sein, das ein veränderter Datensatz in DB1 steht, aber nicht in DB2
Selten kann es vorkommen, das ein Datensatz in DB1 gelöscht wurde, aber in DB2 noch vorhanden ist

Mir geht es eigentlich nur um eine (einfache) Möglichkeit, 2 Tabellen auf 2 Servern bei Bedarf quasi zu synchronisieren.
Da geht es mittlerweile um mehrere tausend Datensätze und mit Copy&Paste ist das einfach nicht mehr wirklich machbar.
Deswegen sagte ich ja, das das Löschen und Neueinlesen wohl der einfachste Weg wäre.
Bitte warten ..
Mitglied: Indrador
29.11.2011 um 16:01 Uhr
Wenn der seltene Fall, dass in DB1 was gelöscht wird
eintritt, soll der Datensatz auch in DB2 weg sein oder?

Wenn das der Fall ist, mach doch einfach folgendes:

Auf DB1 eine View mit dem Tabelleninhalt, die brauchst du nur einmal anlegen und dann nicht mehr ändern.
01.
Create View v_Befuellung_DB2 
02.
AS 
03.
Select * from Daten.dbo.Datentab (nolock) 
04.
GO
Auf Server 2:
01.
Delete from Daten.dbo.Datentab 
02.
GO 
03.
INSERT INTO Daten.dbo.Datentab   
04.
SELECT  * FROM Daten.dbo.v_Befuellung_DB2
Die Codepassage für Server 2 packste dir dann in einen Stores Procedure und die rufst du auf DB 2 einfach stündlich oder täglich Abends per SQLcmd auf,
dann hast du Synchronisierung ohne zutun.
Der bessere Weg wäre das Script direkt als SQL Job laufen zu lassen aber ich meine der Express Server hat keinen SQL Server Agent.

In mittleren bis großen Umgebungen (>1.000.000 Datensätze) würde man sich tatsächlich die Mühe für ein bidirektionales Differenzskript machen
aber bei "mehreren Tausend" Datensätzen, ist die Menge so schwindend gering für eine Datenbank, dass alles löschen und neu reinschreiben
vollkommen okay ist.
Bitte warten ..
Mitglied: Iwan
30.11.2011 um 09:56 Uhr
Mit den Skripten komme ich auf jeden Fall schon mal weiter und spare mir nervenaufreibendes manuelles Kopieren von Daten.
Die Tabelle 'Datentab' war jetzt eigentlich nur ein Beispiel - das ganze werde ich entsprechend auch für andere Tabellen nutzen.

Auf jeden Fall vielen dank noch mal für die Hilfestellung.
Bitte warten ..
Mitglied: Indrador
30.11.2011 um 11:34 Uhr
Kein Problem, dann mal viel Erfolg.
Bitte warten ..
Neuester Wissensbeitrag
Microsoft

Lizenzwiederverkauf und seine Tücken

(5)

Erfahrungsbericht von DerWoWusste zum Thema Microsoft ...

Ähnliche Inhalte
Windows Server
gelöst Update von sql server express 2005 sp4 auf 2008 klappt nicht (11)

Frage von jhaustein zum Thema Windows Server ...

Datenbanken
MS-SQL-Server + T-SQL+Batch (4)

Frage von kallewirsch zum Thema Datenbanken ...

Heiß diskutierte Inhalte
Windows Netzwerk
Windows 10 RDP geht nicht (16)

Frage von Fiasko zum Thema Windows Netzwerk ...

Windows Server
Outlook Verbindungsversuch mit Exchange (15)

Frage von xbast1x zum Thema Windows Server ...

Microsoft Office
Keine Updates für Office 2016 (13)

Frage von Motte990 zum Thema Microsoft Office ...