Das Problem
In JTL-Wawi lässt sich ein bestehendes Bild nicht mit einem Klick an mehrere Artikel hängen. Wer ein Standardbild — etwa ein Kategorien- oder Platzhalter-Bild — für eine größere Artikelmenge nachtragen möchte, steht vor der Wahl: jeden Artikel einzeln öffnen oder direkt in der Datenbank ansetzen.
Der direkte SQL-Weg klingt simpel: ein INSERT INTO tArtikelbildPlattform mit einer Artikelliste als Quelle. In der Praxis stolpert man dabei über mehrere Constraints, die nicht auf Anhieb offensichtlich sind.
Die Datenbankstruktur
Die relevante Tabelle ist tArtikelbildPlattform. Sie verknüpft Bilder (kBild) mit Artikeln (kArtikel) und enthält zusätzlich Plattform-Informationen für Wawi-intern (kPlattform = 1) und eBay (kPlattform = 30).
Die Tabelle hat zwei Unique Keys:
UQ_..._kBild_kArtikel_kPlattform_kShop_kEbayUser— dasselbe Bild darf pro Artikel und Plattform nur einmal vorkommenUQ_..._kArtikel_kPlattform_kShop_kEbayUser_nNr— die Bildposition (nNr) muss pro Artikel und Plattform eindeutig sein
Dazu kommt ein Foreign Key auf tArtikel: jeder einzufügende kArtikel-Wert muss dort existieren.
Der naive Ansatz und warum er scheitert
Ein einfaches INSERT ... SELECT aus einer Quelltabelle wie ebay_item schlägt aus drei Gründen fehl:
1. Bild bereits verknüpft: Einige Artikel haben kBild = 738 bereits — der erste Unique Key verhindert den doppelten Eintrag.
2. Feste nNr kollidiert: Wer nNr = 2 hartcodiert, bekommt eine Kollision, sobald ein Artikel schon zwei Bilder hat.
3. Doppelte Quellzeilen: Eine Quelltabelle wie ebay_item kann denselben kArtikel mehrfach enthalten — z. B. weil ein Artikel in mehreren Angeboten gelistet war. Das NOT EXISTS greift dann nur beim ersten Durchlauf; der zweite identische Insert schlägt trotzdem fehl.
Die robuste Lösung
Das Script löst alle drei Probleme in Kombination:
BEGIN TRANSACTION;
INSERT INTO tArtikelbildPlattform (kBild, kArtikel, kPlattform, kShop, nNr, nInet, kEbayUser, cBildname)
SELECT
738,
e.kArtikel,
1,
0,
ISNULL((SELECT MAX(t.nNr) FROM tArtikelbildPlattform t
WHERE t.kArtikel = e.kArtikel
AND t.kPlattform = 1
AND t.kShop = 0
AND t.kEbayUser = 0), 0) + 1,
0,
0,
''
FROM (SELECT DISTINCT kArtikel FROM ebay_item
WHERE StartTime IS NOT NULL AND EndTime IS NOT NULL) e
WHERE EXISTS (SELECT 1 FROM tArtikel a WHERE a.kArtikel = e.kArtikel)
AND NOT EXISTS (
SELECT 1 FROM tArtikelbildPlattform t
WHERE t.kBild = 738
AND t.kArtikel = e.kArtikel
AND t.kPlattform = 1
AND t.kShop = 0
AND t.kEbayUser = 0
);
-- COMMIT TRANSACTION;
-- ROLLBACK TRANSACTION;
Für kPlattform = 30 (eBay) wird dasselbe Muster mit kEbayUser = 1 wiederholt.
Was das Script konkret tut
SELECT DISTINCT kArtikel — eliminiert doppelte Quellzeilen. Egal wie oft ein Artikel in ebay_item auftaucht, er wird nur einmal verarbeitet.
EXISTS auf tArtikel — filtert Artikel heraus, die in der Wawi-Datenbank nicht (mehr) existieren. Ohne diesen Filter bricht der Foreign Key den Insert ab.
NOT EXISTS auf tArtikelbildPlattform — überspringt Artikel, bei denen kBild = 738 bereits verknüpft ist. Verhindert die Verletzung des ersten Unique Keys.
MAX(nNr) + 1 — berechnet die nächste freie Bildposition pro Artikel dynamisch. Damit landet das neue Bild immer ans Ende — unabhängig davon, wie viele Bilder bereits vorhanden sind.
Fallstricke aus der Praxis
Doppelte Quellzeilen sind unsichtbar. Das NOT EXISTS schützt nur gegen bereits vorhandene Datenbankeinträge — nicht gegen Duplikate innerhalb des gleichen SELECT. Wer DISTINCT weglässt, bekommt beim zweiten Durchlauf einer doppelten Quellzeile dennoch einen Fehler.
Ungültige Artikel prüfen vor dem Ausführen. Die folgende Abfrage zeigt, welche kArtikel aus der Quelle nicht in tArtikel existieren:
SELECT DISTINCT e.kArtikel
FROM ebay_item e
WHERE e.StartTime IS NOT NULL
AND e.EndTime IS NOT NULL
AND NOT EXISTS (
SELECT 1 FROM tArtikel a WHERE a.kArtikel = e.kArtikel
);
Das Ergebnis gibt einen guten Hinweis darauf, ob die Quelldaten sauber sind oder ob gelöschte Artikel darin enthalten sind.
Immer mit ROLLBACK testen. Das Script sollte zuerst mit ROLLBACK am Ende ausgeführt werden — so lässt sich prüfen, ob Fehler auftreten, ohne Daten zu verändern. Erst wenn kein Fehler auftritt, wird ROLLBACK durch COMMIT ersetzt.
Vorgehen bei der Ausführung
- Datenbankbackup erstellen
- Prüfabfrage für ungültige
kArtikelausführen - Script mit
ROLLBACKtesten — auf Fehlermeldungen prüfen - Bei Erfolg
ROLLBACKdurchCOMMITersetzen und erneut ausführen - Stichprobenartig in JTL-Wawi prüfen ob die Bilder korrekt hinterlegt sind
Ergebnis
Nach der Ausführung sind alle Artikel aus der Quelltabelle mit dem gewünschten Bild verknüpft — auf beiden Plattformen, mit korrekter Bildposition und ohne Datenkonflikte. Was über die Oberfläche viele Einzelschritte gewesen wäre, erledigt das Script in einem Durchlauf.
Fazit:
tArtikelbildPlattformist gut strukturiert, aber die zwei Unique Keys und der Foreign Key verlangen eine sorgfältige Insert-Logik. Die Kombination ausDISTINCT,EXISTSund dynamischemMAX(nNr) + 1macht das Script robust gegen alle typischen Fehlerquellen — und wiederverwendbar für beliebige Bilder und Quelltabellen.