PDA

Vollständige Version anzeigen : Tabellenvergleich (noch nirgendwo eine passende lösung gefunden)


Lordas
25.10.2002, 15:00
hallo leute,

vorab: ich habe schon in der hilfe geschaut und habe gerade auch 5 bücher neben mir liegen, aber nichts kann mir so richtig weiterhelfen.

fairerweise muss ich auch sagen, das ich jetzt nicht direkt mit access arbeite, sondern mit SQL-Server 2000 - die resonanz im SQL-Forum aber ein wenig gering ist.

mir geht es hier aber nur um einen evtl. lösungsvorschlag als sql-statement und ich denke den kann man mir auch im access-forum geben.

ich hoffe ihr nehmt mir diese list :D nicht übel?

aber jetzt zu meinem problem:

ich importiere täglich ein file, welches ich auf mehrere tabellen aufteile.

nun ist es so, das dieses file nicht nur neue datensätze enthält (was ja einfach zu filtern ist), sondern auch "alte" datensätze enthält, die geupdated wurden. d.h. irgendwie müsste ich jetzt zwei tabellen vergleichen und dann wissen welche spalte sich gegenüber der anderen tabelle verändert hat und dann die alte tabelle mit den neuen datensätzen überschreiben.

mir fehlt jetzt eigentlich nur noch das statement dazu!!! ich hoffe es kann mir wer helfen :rolleyes:

p.s.: unter vb bzw. vba würde ich das problem ja mit recordsets und der RS.Fields-methode welche ich dann in einer do-loop schleife durchlaufe lösen. ich will aber ungerne dieses problem in vb-skript lösen. ich hoffe es gibt eine lösung.


vielen dank euch schon mal im voraus.

Moderatorenanmerkung: Dieser Beitrag wurde aus dem Access-Forum verschoben!

[ 25. Oktober 2002: Beitrag editiert von: A.S. ]</p>

jmc
25.10.2002, 15:14
Hi
wenn ich das richtig verstehe, dann kommen in der neuen Tabelle immer die kompletten Daten.
Es gibt also im Prinzip keinen Unterschied zwischen den beiden Datensätzen, wenn sich nichts geändert hat.
Warum machst du dann nicht einfach einen kompletten Update? Spielt ja keine Rolle, wenn der Inhalt durch denselben Inhalt überschrieben wird.
Andernfalls müsstest du wohl oder übel mit zig Where-Bedingungen jedes einzelne Feld abfragen damit wirklich nur diejenigen Felder updated werden, die auch ändern ... :mad:

Lordas
25.10.2002, 15:47
ok, also erst mal wollte ich A.S. sagen das ich nicht böse bin ;-) allerdings muss er mir zugestehen, das ich ja nicht mal sagen hätte müssen, das ich auf SQL arbeite und nicht auf access :D . aber egal, ich freue mich schon über eine schnelle antwort von dir jmc.


@jmc

das hast du leider falsch verstanden. die datei, welche täglich kommt, enthält nicht alle daten, sondern nur neue bzw. geänderte.

gibt es sonst wirklich keine möglichkeit und ich muss wieder auf vb-skript umsteigen? ich habe mich gerade so mit sql bzw. t-sql angefreundet (weils ja richtig schnell geht ;-) )

A.S.
25.10.2002, 17:45
Hallo Lordas,

wenn Du nicht erwähnt hättest, das es bei Deinem Problem um pures SQL geht, hätte ich es auch nicht verschoben. Allerdings kann ich vor erwähnten Hintergründen Dir nicht durchgehen lassen, was ich anderen Kategorisch untersage, oder? ;) Von daher war die Verschiebung die notwendige Konsequenz.

Was spricht in Deinem Fall gegen entsprechende SQL-Sequenzen? Zugegeben, werden sie sehr lang und damit zum teil unübersichtlich, aber in Acc sähen sie Beispielsweise für eine 5spaltige Tabelle so aus, wobei 1 Spalte die Index-Spalte ist:

UPDATE Tabelle2
INNER JOIN Import ON Tabelle2.Feld1 = Import.Feld1
SET Tabelle2.Feld2 = [Import].[Feld2],
Tabelle2.Feld3 = [Import].[Feld3],
Tabelle2.Feld4 = [Import].[Feld4],
Tabelle2.Feld5 = [Import].[Feld5]
WHERE (((Tabelle2.Feld2)<>[Import].[Feld2]))
OR (((Tabelle2.Feld3)<>[Import].[Feld3]))
OR (((Tabelle2.Feld4)<>[Import].[Feld4]))
OR (((Tabelle2.Feld5)<>[Import].[Feld5]))
;

In welcher Form Du in SQL bzw. T-SQL den Import auch immer bewältigst, weiß ich nicht. Aber da Du schreibst das Du das schon machst / gemacht hast, solltest Du damit doch kein großes Problem haben, oder? ;)

Um nicht 5 SQL-Sequenzen schreiben zu müssen, damit wirklich nur die geänderte Spalte überschrieben wird, werden gleich alle 5 Spalten upgedatet, wenn sich eine der Spalten geändert hat.

Wie diese Massendatenverarbeitung in SQL einfacher vonstattengehen kann, weiß ich nicht, da ich mich mit dem Bereich noch nicht so intensiv beschäftigt habe.

Gruß

Arno

Lordas
25.10.2002, 17:54
nein arno, ist schon i.o. so, dafür bist du ja auch moderator und ich kenne die mod pflichten, da ich selbst mod bin (in einem anderen forum). also du hast vollkommen richtig gehandelt und ich habe versucht ein hintertürchen zu finden :laugh: - aber dafür war ich ja ehrlich ;)

so, nun aber zu deinem lösungsansatz:

ich seh schon es scheint wirklich nicht viele möglichkeiten zu geben.

eigentlich habe ich nichts gegen solche sql-sequenzen, aber wie du schon schreibst, das wird halt ein wenig viel, vorallem weil es bei mir 22 tabellen sind, die ich vergleichen muss und dann teilweise mit bis zu 50 spalten. daher war ich auf der suche nach einer einfachen lösung.

würdest du dann eher auf die sql-statements zielen, oder doch die vb-skript-lösung bevorzugen?

man will es ja schließlich so einfach wie möglich haben :top:

danke auf jeden fall für deine antwort!

jmc
25.10.2002, 18:02
Hallo Lordas

Arno hat dir ja schon ein sehr schönes SQL-Beispiel hingeschrieben. (Beim SQL-Server fallen einfach die eckigen Klammern und die vielen runden Klammern weg ...)
Nun, wenn du sagst, es kommen nur neue und geänderte, dann ist es ja umso besser.
Die Frage bleibt allerdings, ob du (aus was für Gründen auch immer) nur diejenigen Felder updaten willst, welche sich tatsächlich ändern, oder einfach alles. Dann wäre das Muster von Arno allerdings zu aufwändig, denn:
wenn es nur DS hat, die auch eine Änderung beinhalten (nebst neuen), dann reicht es ja völlig aus, einen Join auf das Key-Feld zu machen, ohne die einzelnen Felder abzufragen, ob sie ändern.
Du hast dann also einerseits ein Update-SQL und andererseits ein Insert-SQL für die neuen DS.
Alles klar ?

Lordas
25.10.2002, 18:41
hallo jean,

ok, das leuchtet mir ein, die neuen datensätze bringe ich ja auch leicht in die richtige tabelle, aber nur durch den join habe ich ja nicht den update.

du meinst dann wohl, das ich den datensatz erst löschen soll und dann einfach neu anlegen soll, wenn der key bereits existiert?

ist das wirklich die vorgehensweise bei datenbankprogrammiereren. ihr müsst wissen, das ich das erste mal mit so großen datenbanken beschäftigt bin, wie in meinen jetzigen projekten.

oder wie hast du deinen vorschlag gemeint?

danke dir schon mal!

jmc
25.10.2002, 23:27
Hi Lordas

also nochmal von vorne:
Es wird immer alles aus der Import-Tabelle verarbeitet!

1) du machst ein Update-SQL mit einem Join der Ziel-Tabelle und der Import-Tabelle über das Key-Feld
Es werden nur diejenigen DS aus der Import-Tabelle verarbeitet, für die ein DS in der Zieltabelle gefunden wird. Logisch, da ja der Join über das Key-Feld geht.
Hier machst du einfach einen Update für alle Felder, also etwa so:

UPDATE Tabelle2
INNER JOIN Import ON Tabelle2.Keyfeld = Import.Keyfeld
SET
Tabelle2.Feld2 = Import.Feld2,
Tabelle2.Feld3 = Import.Feld3,
Tabelle2.Feld4 = Import.Feld4,
Tabelle2.Feld5 = Import.Feld5(nichts von zuerst löschen :nene: )


2) du machst ein ganz normales Insert-SQL (bzw. das hast du ja schon - wie du sagst)
dieses fügt dir alle Datensätze aus der Import-Tabelle in die Zieltabelle bei denen der Key in der Zieltabelle nicht vorhanden sind. Die anderen geben im Prinzip einen Fehler, der aber ignoriert werden kann. Die sind ja schon drin. :idee:

Ist's nun klar ?

Lordas
26.10.2002, 07:43
hi jean,

jetzt ist mir alles klar. :top:

danke für eure hilfe - auf mich wartet noch ein ganzes stück arbeit (mit den vielen tabellen und spalten ;) ).

bis dann

jmc
26.10.2002, 09:12
Hi Lordas

auch schon früh munter.

Von wegen viel Arbeit mit vielen Spalten:
ich habe da mal was geschrieben, um aus der Tabellendefinition entsprechende SQL-Statements zu generieren (Insert und Update), hab's aber im Geschäft und werde am Montag mal den Teil rauspicken. Du müsstest dann lediglich mal die Tabellen in Access einbinden und diese VBA-Funktion laufen lassen. :top:

Gib mir doch auf meine Mail (oben im Beitrag das Icon Brief) kurzes Feedback, ob du interessiert bist.

@Arno (falls er das sieht): nun hat sich der Kreis geschlossen, du kannst jetzt den Thread wieder in's Access-Forum zügeln ... :laugh: :laugh:

A.S.
26.10.2002, 09:59
*g*

Hallo Jean,

gut gemeint, aber Nein - Der Beitrag ist und bleibt ein SQL-Thema und wird nicht zurück ins Acc-Forum verlegt ;)

Immerhin hat der Beitrag im AccForum einen entsprechenden Link hierhin und interessierte an diesem Thema können diesem folgen.

Das man pureSQL-Probleme auch mit Access-Mitteln lösen kann, ist ja eh kein großes Geheimnis ;)

Gruß

Arno

PS Sofern Du die Möglichkeit dafür siehst, währe es schön, wenn Du das Coding hier posten könntest.

Lordas
26.10.2002, 10:01
danke jean,


du hast post

<img src="graemlins/grins.gif" border="0" alt="[grins]" />

A.S.
26.10.2002, 10:18
Hi Ihr beiden ;)

aus purer Neugier habe ich gerade mal google.de angeschmissen und bin hier fündig geworden:

<a href="http://www.freevbcode.com/ShowCode.Asp?ID=3791" target="_blank">http://www.freevbcode.com/ShowCode.Asp?ID=3791</a>

Hab das Teil aber noch nicht getestet ;)

Gruß

Arno

PS Das Teil braucht die "MS Scripting RunTime" und die hab ich nicht auf'm Rechner :( Ist die Freeware und wenn ja, wo kann ich die herbekommen? (Abgesehen davon das ich mich jetzt selbst auf die Suche mache)

[ 26. Oktober 2002: Beitrag editiert von: A.S. ]</p>

A.S.
26.10.2002, 11:25
Hi,

auch dieses Tool bedingt die Anlage der Tabellen in Access.

Das Programm ist in VisualBasic geschrieben. Bei Bedarf kann ich das Exe-File hochladen, da zum Download nur der Source verfügbar ist.

Eine Url zum Erhalt der MS Scripting Runtime ist:

<a href="http://www.microsoft.com/downloads/release.asp?ReleaseID=33065&area=search&ordinal=16" target="_blank">http://www.microsoft.com/downloads/release.asp?ReleaseID=33065&area=search&ordinal=16</a>

direkt bei MS. Die Runtimes von VB sowie diese Komponenten

'References Taken:
'
'Visual Basic For Applications
'Visual Basic runtime objects and procedures
'Visual Basic objects and procedures
'OLE Automation
'Microsoft DAO 2.5/3.51 Compatibility Library
'Microsoft Scripting Runtime
'
'Components Used:
'Microsoft Common Dialog Control
'Microsoft Data Bound Grid Control
'Microsoft Datagrid Control 6.0 (OLEDB)
'Microsoft Flexgrid Control 6.0
'Microsoft Tabbed Dialog Control 6.0
'Microsoft Windows Common Controls 6.0

werden benutzt, sollten also vorhanden sein.

Gruß

Arno

Lordas
26.10.2002, 13:59
ja arno, kannst du es hochladen oder mir per mail senden?

das wäre super!!!

A.S.
27.10.2002, 21:37
Hallo Lordas,

sorry, habe erst jetzt wieder hier vorbei geschaut ;)

Die Datei steht <a href="http://downloads.access-help.de/MDBVIEWER.zip" target="_blank">hier zum Download bereit</a>.

Es handelt sich nicht um ein Setup, sondern lediglich um ein ca. 20 KB großes ZIP-Archiv mit dem .exe-File der Anwendung. Die o.g. Komponennten (also derren installiertsein und ordnungsgemäße Registrierung) sowie eine VB5/6-Runtime (ob's auch mit der 5er geht habe ich allerdings nicht probiert), sollten ebenfalls vorhanden sein.

Gruß

Arno

jmc
28.10.2002, 09:10
Hallo zusammen

war am Wochenende offline .. Da hat sich ja noch einiges getan. :eek:

@Arno: Danke für deine Bemühungen. Habe das Teil (mdbviewer.exe) mal angeschaut. In der Zwischenzeit auch meine Access-Lösung gefunden. Mein Ansatz war damals, die Tabellen einzubinden und auch mit einer Form das ganze zu steuern.
Den Code posten ist etwas viel, zudem fehlt dann das Form. Aber ich könnte das ganze so überarbeiten, dass es benutzerfreundlich ist und dann zur Verfügung stellen.

@Lordas: habe dir ja schon gemailt, ist in Arbeit

Lordas
28.10.2002, 09:34
ganz herzlichen dank für eure hilfe und mühe.

:top:

Lordas
28.10.2002, 13:43
hallo leute,

habe nur ein kleines update zu machen!

d.h. der code von jean stimmt nicht ganz (falsche syntax) richtig lautet er folgendermaßen:


UPDATE Tabelle2 SET
Tabelle2.Feld2 = Import.Feld2,
Tabelle2.Feld3 = Import.Feld3,
Tabelle2.Feld4 = Import.Feld4,
Tabelle2.Feld5 = Import.Feld5
FROM Tabelle2
INNER JOIN Import
ON Tabelle2.Keyfeld = Import.Keyfeld


:D

Steinadler
28.10.2002, 14:09
Hallo
Verstehe ich das richtig, die importierst täglich daten von einer Datenbank bzw. Datei in den SQL Server. Für diese Aufgabe gibt es DTS. Du kannst dabei einfach mit Identity_Insert auch alle geänderte Daten einfügen. Du hast dabei nur ein Problem: wenn Du den selben Datensatz in SQL-Server und in der Fremddatei geändert hast, mußt Du entscheiden, welchen du behalten willst.
DTS kannst du auch zeitgesteuert automatisch ablaufen lassen.

Lordas
28.10.2002, 14:58
@steinadler

DTS benutze ich, allerdings von diesem "identity_insert" hatte ich bisher noch nicht viel gehört. kannst du mir das genauer erklären? soviel ich weiß wird dadurch doch nur ein integer-feld angelegt (autowert), oder?

danke
lordas

Lordas
28.10.2002, 15:12
STOP!!

mir fällt sowieso gerade ein, das ich DTS leider nicht ganz so hernehmen kann, wie es mir gefallen würde.

die datei, die ich nämlich importiere enthält verschiedene satzarten, mit unterschiedlicher datensatzlänge.

d.h. ich habe z.b. einen kundenstamm mit einer länge von 800 zeichen und dann habe ich einen artikelstamm mit einer länge von nur 500 zeichen.

die einzelnen satzarten haben auch einen unterschiedlichen aufbau, d.h. ich muss sowieso fixed-field einlesen. allerdings scheint der sql-server da einen kleinen bug zu haben. versuche mal eine datei mit unterschiedlichen satzarten (und eben zuglich verschiedenen satzlängen) über den DTS zu importieren. der sql-server importiert das nicht richtig, egal welche rowdelimiter du ihm gibst. er richtet sich immer nach dem ersten datensatz. die anderen gleicht er immer der länge des ersten an.

versuchs mal.

Lordas
28.10.2002, 16:18
@arno

leider funktioniert die exe bei mir nicht. es kommt immer die fehlermeldung, das das dbgrid32.ocx fehlt (datagrid-steuerelement). das scheint aber auch nicht in der vb6-runtime drin zu sein. kann ich das einfach nachinstallieren? wenn ja wohin?

danke

Lordas
28.10.2002, 16:31
sorry, hat sich schon erledigt (habe es mir schon besorgt und reinkopiert.

jetzt funktionierts!

ist allerdings nicht ganz so der hit - viel machen kann man nicht damit. aber egal, ein versuch war´s wert. jetzt hoffe ich noch auf jean bzw. auf eine weitere nachricht zum "identity_insert"

Steinadler
30.10.2002, 10:54
Hallo

Ich sag mal, wie ich neue und geänderte Daten importiere.
Ich baue einen SQL-task zum löschen der geänderten Datensätze. Dadurch sind alle Daten neu.
Danach einen Workflow und einen SQL-Task zum anhängen aller Daten.
identity Insert braucht man wenn man ein Autowertfeld hat, weil man ja Daten mit kleinerer ID als der Autowert einfügen muß.
idententy Insert erlaubt gelöschte Datensatz-IDs in Autwertfelder aufzufüllen.
Wenn man kein Autwertfeld hat, braucht man kein identity insert.
bei komplexen daten kann man beim importieren auch den Umweg über den Analysis-Service machen..... dieser ist sehr flexibel mit der Datenanalyse - Vorsicht, nicht mit Live-Daten arbeiten.