PDA

Vollständige Version anzeigen : Schlüsselverletzung


magic1708
19.10.2011, 11:33
Hallo zusammen,

ich bekomme beim Import einer Excel Datei in eine bestehende DB ( Anfügeabfrage) eine Schlüßelverletzung für jeden eintrag.

Die Spalten sind in der Excel Datei und der Access Tabelle identisch.

Wenn ich die Meldung mit Ja beantworte also "Soll Acces trotzdem die Daten importieren" wird dieses Fehlerfrei gemacht.

Hat jeamdn eine Idee wie ich das beheben kann? Oder vll umgehen kann.

Gruß Matthias

ebs17
19.10.2011, 11:55
Lerne die Definitionen in Deiner Datenbank kennen:
- Die Tabellendefinition der Zieltabelle und dort gezielt die hinterlegten eindeutigen Indizes.
- Die Beziehungen dieser Tabelle zu anderen Tabellen.

Eine Tabelle ist halt kein Topf, wo man alles rein werfen kann, sondern die genannten Festlegungen bestimmen und überwachen, was wie hinein darf.
Wenn Du Deine Abfrage in Einklang mit diesen Festlegungen gestaltest, entfallen Fehlermeldungen. Zusätzlich wirst Du dann weniger Daten bewegen (weil die unnützen weggelassen werden). Weniger Arbeit => kürzere Verarbeitungszeit.

CptChaos
19.10.2011, 12:20
OT: Wenn Du Deine Abfrage in Einklang mit diesen Festlegungen gestaltest, entfallen Fehlermeldungen
Das hat ja schon fast was von ZEN ;) SCNR

magic1708
19.10.2011, 14:30
Kann man das noch mal für mich zusammen fassen ??

Verstehe nur Bahnhof.

Atrus2711
19.10.2011, 14:42
Nicke zu folgenden Aussagen oder melde dich:

Deine Tabellen haben einen Primärschlüssel
Du importierst einen Bestand von außen in die Tabelle
--> "Duplikate" verletzen den Schlüssel.
Sinnvoll wäre ein "selektiver Import": nur die, die es am Ziel noch nicht gibt. Das geht so direkt nicht.
Du kannst aber die Exceldateien verknüpfen oder in eine Puffertabelle importieren. Von dieser Stelle aus vergleichst du mit den vorhandenen Daten und fügts nur die fehlenden an. Stichwort: Inkonsistenzabfrage

ebs17
19.10.2011, 14:54
Martin, schlag mich, aber Du machst hier keine Zusammenfassung (das dürfte aber auch schwierig sein), sondern eine Detaillierung.
Eindeutiges Indizes würde ich auch nicht auf den Primary Key reduzieren.

@magic1708: Kennst Du die Entwurfsansicht für Tabellen? Dort wird die Tabellendefinition festgelegt (Felddatentypen, Gültigkeitsregeln, Pflichtfelder und einiges anderes). Zu den Indizes kommst Du dann über das Menü oder eine Symbolschaltfläche.

Was ein Index ist, weißt Du?

Atrus2711
19.10.2011, 14:59
schlag mich
Nur in Notwehr :) ich glaube mein Beitrag hilft dem Frager eher weiter...

magic1708
19.10.2011, 15:43
•Deine Tabellen haben einen Primärschlüssel ---> Jap
•Du importierst einen Bestand von außen in die Tabelle --> jap aus Excel (aufbau der Tabelle gleich (also Spaltennamen) )
•--> "Duplikate" verletzen den Schlüssel.
Spalte "Auftraggeber" hat den PK und da steht drin Indiziert: Ja (ohne Duplikate)
•Sinnvoll wäre ein "selektiver Import": nur die, die es am Ziel noch nicht gibt. Das geht so direkt nicht.
•Du kannst aber die Exceldateien verknüpfen oder in eine Puffertabelle importieren. Von dieser Stelle aus vergleichst du mit den vorhandenen Daten und fügts nur die fehlenden an. Stichwort: Inkonsistenzabfrage


Excel wird also verknüpfte Tabelle importiert.... Mache ich so :
http://www.ms-office-forum.de/forum/showthread.php?t=281994&page=2

Was ist ein selektiver Import??

Danke für eure Hilfe....

Atrus2711
19.10.2011, 15:47
Was ist ein selektiver Import??
Ein "Import der Fehlenden". Aber den gibts ja nicht. Mit dem Einlesen aller Sätze und dem anschließenden Anfügen der Fehlenden kannst du dir behelfen.

magic1708
19.10.2011, 15:48
ebs17

Ich kenne diese Funktion schon... Werde mit denen aber bestimmt nicht so gut umgehen können wie du... Ich mache grad mein 2. größeres Projekt (was bei dir ein kleines wäre :) )

Index müsste das Ding sein was ich immer per Autowert erstellen lasse oder?? Die nummereierung der DS.

Atrus2711
19.10.2011, 15:55
Atrus' kleines Access-Lexikon:

Primärschlüssel = Feld mit dem Schlüsselsymbol im Tabellenentwurf = gewähltes eindeutiges Merkmal aus ein oder (selten) mehreren Feldern; i.d.R. für "Beziehungsanbindung" im Datenmodell genutzt.
Index = Navigationshilfe für die Datenbank, vergleichbar einem Index in einem Buch. Ohne Index muss eine Suche immer die ganze Tabelle/das ganze Buch durchstöbern.
Eindeutiger Index: Index, in dem jeder Wert nur einmal vorkommen kann. Ähnlich dem Primärschlüssel, aber Unterschied: physische Reihenfolge auf der Platte wird nicht verändert. Meist nur als "Nebenbedingung" genutzt, um zusätzlich zum Primärschlüssel ein "kann-ebenfalls-nicht-mehrfach-vorkommen" durchzusetzen.
Autowertfeld: Feld des Datentyps Autowert. Gut geeignet für Primärschlüssel, muss aber nicht zwingend sein.

magic1708
19.10.2011, 15:57
@Atrus...

Ich kenne diese Tabelle die erstellt wird wenn es import fehler gab. diese erstellt access in dem fall nicht. sonder importiert alles DS ohne sichtlichen Fehler.

magic1708
19.10.2011, 16:01
So sieht meine Tabelle aus:

Und die Beziehung

http://www.ms-office-forum.de/forum/attachment.php?attachmentid=57740&d=1315466944

Atrus2711
19.10.2011, 16:13
Ich kenne diese Tabelle die erstellt wird wenn es import fehler gab.
Von der war keine Rede.

Der Gedanke war, die Exceltabelle zu verknüpfen (statt importieren) oder in eine Puffertabelle (statt der eigentlichen Zieltabell) zu importieren. In beiden Fällen entsteht eine Tabelle, die den Excel-Stand darstellt. Und der kann dann mit dem bisherigen Acces-Stand verglichen werden.

magic1708
19.10.2011, 16:19
Die Exceltabelle ist verknüpft.

Atrus2711
19.10.2011, 16:25
Fein. Dann schau dir den letzten Punkt in #5 an:
• Du kannst aber die Exceldateien verknüpfen oder in eine Puffertabelle importieren. Von dieser Stelle aus vergleichst du mit den vorhandenen Daten und fügts nur die fehlenden an. Stichwort: Inkonsistenzabfrage
Du fügst bisher immer noch alle Excel-Sätze an, nicht nur die fehlenden. Und da gibts dann natürlich Mecker wegen Schlüsselverletzungen.

magic1708
19.10.2011, 16:47
In dieser Inkontinenz abfrage kommt auch nix bei raus. Die ist schlicht weg leer.

CptChaos
19.10.2011, 16:52
Frage: Ist das Ergebnis welches Du bekommst, wenn Du den Hinweis mit "Ja" beantwortest denn fachlich für Dich richtig?

Dann wäre es evtl. einfacher vor dem Import der Daten die bestehenden zu löschen oder besser zu archivieren (in einer eigenen Tabelle).

Kannst Du evtl. etwas zum fachlichen Hintergrund der Aktion sagen?
Handelt es sich hier evtl. um eine "fortlaufende" Liste die als Excel vorliegt und in Access verarbeitet wird?

magic1708
19.10.2011, 17:05
Es ist eine Tabelle in der alle Kunden von Niederlasung X hinterlegt sind. Diese Tabelle wird in regelmäßigen abständen aktualisiert. D.h es werden Kunden gelöscht und auch hinzugefügt. Wobei das hinzufügen für meine sache im vordergrund steht.
Ich habe da eine Angebotsverfolgung am laufen. Nur die KundenDaten werden alle aktueller also muss ich eine möglichkeit schaffen wie man einfach per Knopfdruck die daten aktualisiert.

Das was beim drücken von Ja rauskommt ist völlig korrekt. Deswegen wundert mich diese Meldung.

CptChaos
19.10.2011, 17:11
Die Meldung kommt schlicht und ergreifend daher, dass irgendjemand (evtl. Du selbst?) die Ziel-Tabelle so definiert hat.

Wenn die Daten die hier offenbar wiederkehrend immer das Soll darstellen hast Du m.E. folgende Möglichkeiten:

1. Immer alles (blind) übernehmen
Heißt, die bestehenden (möglicherweise veränderten) Daten in der Datenbank ignorieren und löschen/archivieren/überschreiben
2. Einen Abgleich der bestehenden mit den neuen Daten machen
Dabei ergibt sich dann, dass z.B. 100 DS bestehen, in der "Neulieferung" 120 enthalten sind.
Somit hast Du 20 DS hinzuzufügen und 100 ggf. zu aktualisieren (Kunde Nr. 78 ist umgezogen und somit stimmt die Adresse nicht mehr)
3. Um eine Historie zu erhalten alle DS aus Excel anfügen (somit würden um bei obigem Beispiel zu bleiben aus den 100 DS dann 220 (100+120))
Über entsprechende Abfragen, etc. könnte dann aggregiert werden und Du könntest feststellen dass Kunde Nr. 78 umgezogen ist

magic1708
20.10.2011, 08:48
Hey Danke für Eure Hilfe, und viele dank an den der meinen Schreibfehler in der Überschrift korrigiert hat :-)

Mir ist es nicht wichtig in diesem Fall ob sich ein DS geändert hat. Wichtig ist nur Kundennummer und Name das muss zusammen passen und aktuell sein.

Für Sachen ob der Kunde umzieht und was sich da noch alles machen lässt haben wir SAP. :-)

Ich bekomme von einer Vertriebsstelle die Fertige Excel Datei. Diese muss ins Access.
Da ich auch älter Angebotsbestände in der Datenbank habe wäre es nicht schlimm wenn gelöschte (in SAP) DS in der Access Datenbank noch bestehen würde.
Von daher würde es mit dem Anfügen reichen?!

Da bin ich doch mit meinem Beispiel nicht schlecht dabei oder?? Ich lösche zwar im Moment die alten DS und Füge die neuen an. (Das dauert vll wenn es hochkommt 30 Sekunden).

Aber was muss ich den machen um entweder in meiner Automatik (diese läuft überhaupt nicht an, bei den Test jedoch schon!) die Fehler Meldung zu deaktivieren und den Code durchlaufen zulassen.... Oder so einzustellen das es keine Fehler gibt.... Die scheint es ja auch nicht zugeben.


Gruß

Atrus2711
20.10.2011, 10:31
Hi,

In dieser Inkontinenz abfrage kommt auch nix bei raus. Die ist schlicht weg leer.
:yelrotfl: Eine Inkontinenzabfrage gibts beim Urologen. Hier gehts um eine Inkonsistenzabfrage.

Wie sieht deine denn aus? Ihr Sinn ist da, die fehlenden anzufügen. Je nach Aufbau erkennt sie die fehlenden nicht richtig und fügt dann auch nichts an, weil "nichts fehlt".

magic1708
20.10.2011, 11:01
Gut erkannt :-)

Was meinst du mit aufbau... Ich habe den Assisteneten benutzt und zuerst die Acces DB und als zweites die Excel Tabelle ausgewählt. Dann habe ich die über Auftraggeber sprich die eindeutige Kundennummer verbunden.

Atrus2711
20.10.2011, 11:09
Deine Abfrage (Bild in #15) greift nicht auf die Tabelle der Vorhandenen zu, sondern nur auf die Exceltabelle.
http://ms-office-forum.de/forum/showpost.php?p=1409068&postcount=15

Oder hast du inzwischen die Abfrage verändert? Dann zeig mal her.

Grundsätzlich sollte das so laufen wie Donkarl zeigt:
http://www.donkarl.com?FAQ3.16
Diese Sätze wären dann anzufügen.

magic1708
20.10.2011, 11:31
HIer mal die Inkonsistenzabfrage

Atrus2711
20.10.2011, 11:37
Wenn du die Sätze aus der Excelliste, die in den Accessliste noch fehlen, übernehmen willst, ist die Pfeilrichtung falschherum.

Zudem fehlt ein Kriterium (oder es ist im Bild nicht ersichtlich), das die Auftraggebernummer der Accesstabelle auf Is Null testet.

magic1708
20.10.2011, 12:09
Dann hier noch mal mit dem gleichen ergebnis andersrum

Atrus2711
20.10.2011, 12:13
Hi,

ja, die sieht gut aus. "Fehlend" wird in diese Abfrage ausschließlich an der Nummer ermittelt, d.h. es wird unterstellt, dass eine Nummer in beiden Tabelle denselben Kunden bezeichnet. Wenn das nicht der Fall ist, mach dir mal Gedanken, was einen Kunden eigentlich ausmacht.

magic1708
20.10.2011, 12:28
So soll es stimmen... Fehlen kann im moment nix... Sind ja gleichen inhalte drin...

Die Fehlermeldung ist dadurch aber immer noch nciht behoben......

Atrus2711
20.10.2011, 12:40
Hi,

wenn die Exceltabelle verknüpft ist, kann sie selbst keine Primärschlüssel oder eindeutige Indizex haben, die da verletzt würden. Entweder du hast die Daten doch importiert (und in der entstehenden Puffertabelle sollte es keine PKs geben), oder du fügst andere Daten an als die, die die Inkonsistenzabfrage liefert.

Eine DB-Hochladen wäre hilfreich.

ebs17
20.10.2011, 12:43
Die Fehlermeldung ist dadurch aber immer noch nciht behoben......
Die Fehlermeldung ist vielleicht nur eine Statusmeldung. Wie führst Du Deine Abfrage aus?

magic1708
20.10.2011, 14:09
Also sollte ich mir ersteinmal die Excel Daten in eine Zwischentabelle ziehen.. Und von da aus in die Kundendaten?

In der Puffertabelle kann ich ja vom PK absehen?! oder diesen auf ID setzten.

magic1708
20.10.2011, 14:11
@ebs17 wie vorne der Code beschrieben ist. Leider ist diese nicht durchgelaufen. Beim Debuggen ist mir der Fehler aufgefallen. Ist eine Gelbe Meldung. Das ist diese Standardmeldung Bei Schlüßelverletzung.

Die DB würde ich ungern in dieser Konsetzelation so posten...

Atrus2711
20.10.2011, 14:36
Also sollte ich mir ersteinmal die Excel Daten in eine Zwischentabelle ziehen.. Und von da aus in die Kundendaten? In der Puffertabelle kann ich ja vom PK absehen?! oder diesen auf ID setzten.

Ja, das war die Idee. Seit #5...

magic1708
20.10.2011, 15:37
Hätte Ihr doch gleich sagen können :-) :-) :-)

Ne spass... Ich werde das mal so probieren... Folglich muss ich dann 2 anfüge Abfrage für die Automatisierung machen oder??

Danke schön.

Gruß

Atrus2711
20.10.2011, 15:38
Eine für jede betroffene Zieltabelle. Ich sehe da nur eine.

magic1708
20.10.2011, 16:19
Jap im Moment ist es auch nur eine... War eine Frage..

Folglich mache ich eine Anfüge Abfgrage Excel---> Hilfstabelle und eine Hilfstabele--> tbl_Kundenliste ??

Danke für die wirklich Gute Hilfe!!

Gruß Matthias

Atrus2711
20.10.2011, 16:23
Ja, wobei du die Anfüge von Excel->Hilfstabelle sparen kannst, wenn du die Exceltabelle verknüpfst. Die kannst du dann in Access lesen, als sei es eine Accesstabelle. Dadurch kannst du sie insbesondere in der Inkonsistenzabfrage mit dem Bestand vergleichen.

Manche der Beiträge, die dir zur Hilfe eilen, sollten gelesen und verstanden werden. Wenn letzteres nicht klappt, frag nach.

ebs17
20.10.2011, 18:52
In der Nachfolge ein Beispiel der Aktualisierung einer Tabelle mit einer Exceltabelle, wobei hier Aktualisierung heißt, nur die jeweils benötigten Datensätze zu bewegen und dann eben nicht alles zu löschen und alles anzufügen. Weniger Arbeit sollte dann auch weniger benötigte Zeit nach sich ziehen:
Sub test()
Dim db As DAO.Database
Const Exceldatei As String = "X:\irgendwo\eine.xls"
Set db = CurrentDb

' Verknüpfen
DoCmd.TransferSpreadsheet acLink, acSpreadsheetTypeExcel7, "Quelltabelle", Exceldatei, True

' Dezidiertes Aktualisieren - Annahme: Es gibt zwei Schlüsselfelder ... Key1, Key2

' 1. Löschen veralteter Datensätze bzw. Deaktivieren über Löschvermerk
' db.Execute "DELETE FROM Zieltabelle Z WHERE NOT EXISTS (SELECT Null FROM Quelltabelle Q" & _
' " WHERE Q.Key1 = Z.Key1 AND Q.Key2 = Z.Key2)", dbFailOnError
db.Execute "UPDATE Zieltabelle Z SET Z.Loeschvermerk = True WHERE NOT EXISTS" & _
" (SELECT Null FROM Quelltabelle Q WHERE Q.Key1 = Z.Key1 AND Q.Key2 = Z.Key2)", _
dbFailOnError

' 2. Aktualisieren von vorhandenen Datensätzen, hier nur zwei Felder
db.Execute "UPDATE Zieltabelle Z INNER JOIN Quelltabelle Q ON Q.Key1 = Z.Key1" & _
" AND Q.Key2 = Z.Key2 SET Z.Feld1 = Q.Feld1, Z.Feld2 = Q.Feld2", dbFailOnError

' 3. Anfügen von nur neuen Datensätzen (ohne Berücksichtigung von Autowerten)
db.Execute "INSERT INTO Zieltabelle (Key1, Key2, Feld1, Feld2)" & _
" SELECT Q.Key1, Q.Key2, Q.Feld1, Q.Feld2 FROM Quelltabelle Q WHERE NOT EXISTS" & _
" (SELECT Null FROM Zieltabelle Z WHERE Q.Key1 = Z.Key1 AND Q.Key2 = Z.Key2)", _
dbFailOnError

' Entlinken
DoCmd.DeleteObject acTable, "Quelltabelle"
Set db = Nothing
End Sub
Statt des Ver- und Entlinkens könnte man man die Verbindungsdaten zur Exceltabelle direkt in die Abfragen übernehmen.

Bezüglich oben vermeldeten Schlüsselfehler: Vielleicht lohnt sich doch ein Blick in die Indexauflistung der Zieltabelle (gucke hier (http://www.ardiman.de/datenbanken/grundlagen/tabellen.html#SEC1)). Vielleicht gibt es ja neben dem Primärschlüssel noch weitere eindeutige Indizes ...