Komplexe SQL Kopiervorgänge (insert ignore)
Mit SQL lassen sich Daten in einer Datenbank sehr schnell und effizient manipulieren. Es gibt aber auch oft Situationen in denen Programmierer überfordert sind und lieber ein kleines Programm schreiben um eine komplexe Aufgabe zu erledigen. Das ist aber nicht immer notwendig und kann sehr oft sogar auch mit einem SQL Statement abgearbeitet werden. In diesem Artikel geht es genau um solche SQL Statements.
Kopieren und Einfügen
Das Kopieren und Einfügen gehört bei allen Betriebssystemen zu den wichtigsten Funktionen überhaupt und wird auch auf Programmebene so oft als möglich angeboten. Beispiele sind der Explorer, ein Textprogramm oder der Browser.
Kopieren
Ich möchte schnell aus einer Datenbank mit mehreren Tausend Zeilen alle Datensätze mit einem bestimmten Wert kopieren. Die zu kopierenden Datensätze hole ich mir wie folgt:
SELECT * FROM user WHERE game_id = 1;
Ich hole mir alle Benutzer mit der game_id von 1. All diese Benutzer möchte ich nun wieder in die Tabelle einfügen, jedoch mit einer anderen game_id.
Einfügen
Nun möchte ich all diese Datensätze mit der game_id 2 in die selbe Tabelle einfügen. Da der Primärschlüssel ein Autowert ist, brauche ich diese Spalte nicht angeben. Damit wird jedem neuem Datensatz automatisch ein neuer eindeutiger Schlüssel zugeordnet. Einfügen kann ich nun die zuvor ausgewählten Werte wie folgt:
INSERT INTO users (game_id, name, login, passwort) (SELECT 2, name, login, passwort FROM user WHERE game_id = 1);
Wie man sehen kann habe ich das SELECT Statement um die Angabe der einzelnen Spalten erweitert. Außerdem habe ich einen konstanten Wert 2 für die Spalte game_id angegeben. Im INSERT Statement habe ich alle verwendeten Spalten ebenso angegeben.
Mit diesem kurzen Statement wird eine beliebige Anzahl an Datensätzen kopiert und in die selbe Tabelle mit neuen Primärschlüsseln eingefügt.
Insert Ignore
Was passiert nun, wenn im oben genannten Beispiel die Kombination aus game_id und name aus irgend einem Grund eindeutig sein muss und man bereits einige Datensätze für game_id = 2 händisch eingegeben hat? Das Insert Statement würde bei einem Fehler abbrechen und die Transaktion würde abgebrochen. Es würden keine Datensätze eingefügt werden.
Wenn man eine Transaktion eines INSERT Statement vor gelegentlich auftauchenden nicht einzufügenden Inserts schützen möchte kann man das Schlüsselwort IGNORE verwenden. Damit werden fehlerhafte Inserts einfach ignoriert und so viele Datensätze wie möglich importiert. Das oben genannte Statement schaut nun folgendermaßen aus:
INSERT IGNORE INTO users (game_id, name, login, passwort) (SELECT 2, name, login, passwort FROM user WHERE game_id = 1);
Schon haben wir unser fertiges Kopieren und Einfügen Statement! Bereits vorhandene Datensätze werden ignoriert und lassen den Import nicht abbrechen.