Fehlerabfrage

Fehlerabfrage

am 14.10.2007 20:48:32 von letters

Hallo,

ich habe eine CSV Datei, die ich in eine Datenbank einlesen möchte. Die DB
selbst besteht aus über 50 Tabellen. Die Daten dafür sind aber alle in
einer CSV Datei. Da diese CSV Datei auch mal über mehrere 10.000 datensätze
enthalten kann, lses ich diese erst mal direkt in eine temporäre Tabelle
ein. Dann lese ich diese Tabelle Zeile für Zeile aus und prüfe die Werte
bestimmter Felder auf Überienstimmung mit verschiedenen Werten wie z.B.
Farbe, Kategorie, Hersteller, u.s.w.
Nun kann es aber vorkommen, dass die Datei nicht ganz in Ordnung ist. Z.B
kann es sein, dass eine Hersteller ID 86 eingetragen wird, die aber in der
Datenbank gar nicht existiert. Mit einem Left Join würde mir der Datensatz
dann zwar ausgegeben, aber ohne Wert für die Hersteller ID. Das gibt
Problem bei der Eingabe in die eigentliche Tabelle. Lasse ich einen
Standardwert zu, kann es zu vollkommen unsinnigen Datenbankeinträgen
kommen. Mit einem INNER JOIN wird der Datensatz einfach weggelassen. Das
Mache ich momentan. Ich prüfe auf Erfolg und kann dann den betreffenden
Datensatz aussortieren. Allerdings habe ich dann keine Ahnung, wo nun der
Fehler lag. Bei etwa 20 verschiedenen ID´s müßte ich die alle prüfen. Wenn
nun der INNER JOIN einen Datensatz nicht erfasst, gibt es dann eine
Möglichkeit, herauszufinden warum? Oder anders, wenn eine Datenbankabfrage
fehlschlägt weil der gesuchte Wert nicht in der gejointen Tabelle ist, kann
ich dann feststellen welcher Wert das war?

mfg

Mathias

Re: Fehlerabfrage

am 14.10.2007 22:56:36 von Thomas Rachel

Mathias Fiedler schrieb:

> Hallo,
>
> ich habe eine CSV Datei, die ich in eine Datenbank einlesen möchte. Die DB
> selbst besteht aus über 50 Tabellen. Die Daten dafür sind aber alle in
> einer CSV Datei. Da diese CSV Datei auch mal über mehrere 10.000 datensätze
> enthalten kann, lses ich diese erst mal direkt in eine temporäre Tabelle
> ein. Dann lese ich diese Tabelle Zeile für Zeile aus und prüfe die Werte
> bestimmter Felder auf Überienstimmung mit verschiedenen Werten wie z.B.
> Farbe, Kategorie, Hersteller, u.s.w.

Soweit klar.


> Nun kann es aber vorkommen, dass die Datei nicht ganz in Ordnung ist. Z.B
> kann es sein, dass eine Hersteller ID 86 eingetragen wird, die aber in der
> Datenbank gar nicht existiert. Mit einem Left Join würde mir der Datensatz
> dann zwar ausgegeben, aber ohne Wert für die Hersteller ID.

Stop.

Deine Applikation macht diesen Inner Join/Left Join? Reines Select, so
daß sie sich die Daten liefern läßt, oder ist es ein INSERT INTO ...
(...) SELECT ...?

Ich gehe mal davon aus, daß Du die Daten in die Applikation liest, und
dort das Zeug genau prüfst. Das von Dir beschriebene Problem kriegst Du
durchaus mit einem LEFT JOIN in den Griff, wenn ich Deine Vorgehensweise
richtig deute. Du kannst im Falle eines LEFT JOIN:

* den Wert des Verknüpfungsfeldes der "linken" Tabelle ausgeben lassen
(der enthält immer den dort stehenden Wet)

* den Wert des Verknüpfungsfeldes oder auch jedes anderen Feldes der
"rechten" Tabelle ausgeben lassen (der enthält, sofern vorhanden, den
dortigen Wert, ansonsten NULL).


Beispiel:

CREATE TEMPORARY TABLE a (id int);
CREATE TEMPORARY TABLE b (id int, descr varchar(10));
INSERT INTO b (id,descr) VALUES (1,'erste'),(2,'zweite'),(3,'letzte');
INSERT INTO a (id) VALUES (1),(2),(3),(4);

Nun kann ich (hier: 5.0.26) verschiedene Queries absetzen:

SELECT * FROM a LEFT JOIN b USING (id); -- /* Du weißt ja, SELECT * ist
böse! Nur für Testzwecke einsetzen! */
+------+--------+
| id | descr |
+------+--------+
| 1 | erste |
| 2 | zweite |
| 3 | letzte |
| 4 | NULL |
+------+--------+

SELECT id FROM a LEFT JOIN b USING (id);
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
+------+
(nicht sehr spannend)

SELECT coalesce(descr,'Das da gips net!') FROM a LEFT JOIN b USING (id);
+------------------------------------+
| coalesce(descr,'Das da gips net!') |
+------------------------------------+
| erste |
| zweite |
| letzte |
| Das da gips net! |
+------------------------------------+

SELECT coalesce(descr,concat('Ersatz - #',id)) AS desc_mod FROM a LEFT
JOIN b USING (id);
+-------------+
| desc_mod |
+-------------+
| erste |
| zweite |
| letzte |
| Ersatz - #4 |
+-------------+

Auf diese Art und Weise kannst Du Dir präzise signalisieren lassen, was
wo fehlt.

> Das gibt Problem bei der Eingabe in die eigentliche Tabelle. Lasse ich
einen
> Standardwert zu, kann es zu vollkommen unsinnigen Datenbankeinträgen
> kommen.

Klar, deshalb prüfst Du ja auch vorher.


> Mit einem INNER JOIN wird der Datensatz einfach weggelassen. Das
> Mache ich momentan. Ich prüfe auf Erfolg und kann dann den betreffenden
> Datensatz aussortieren.

Du kannst ja auch so vorgehen, daß Du alle Datensätze, die in Ordnung
sind, direkt übernimmst und die problematischen
ausfilterst/anzeigst/whatever.


> Allerdings habe ich dann keine Ahnung, wo nun der
> Fehler lag. Bei etwa 20 verschiedenen ID´s müßte ich die alle prüfen.

Ist ja kein Problem.


> Wenn nun der INNER JOIN einen Datensatz nicht erfasst, gibt es dann eine
> Möglichkeit, herauszufinden warum?

Ja klar. LEFT JOIN mit WHERE . IS NULL.
Da weißt Du dann, daß es diesen Fremdschlüssel in der rechten Tabelle
nicht gibt und kannst entsprechende Schritte ergreifen.

Kannst Du die Tabellenstruktur (zumindest vom Prinzip her, falls es
Firmengeheimnis oder so ist) hier mal posten? Also, die Ausgabe von SHOW
CREATE TABLE auf die einzelnen Tabellen inkl. Temp-Tabelle angewandt...


Thomas