Sql Insert Into nur einmal?

3 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

Die Existenz bestimmter Einträge sollte anhand ihres Primärschlüsselwerts leicht prüfbar sein. Wenn es zudem relevant ist, sie später leichter zu aktualisieren, kann man tatsächlich darüber nachdenken, zusätzlich eine Versionsnummer oder einen Zeitstempel zu hinterlegen.

SQLite unterstützt INSERT OR REPLACE-Queries.


SamanthaI 
Beitragsersteller
 26.08.2024, 20:16

Insert or ignore sounds good thank you

Hä? Ein Insert schreibt dir bei einem Insert das ganze 5x in die Datenbank? Das ist nicht normal!

Typische Anfängerfehler, die zu komischem Datenbankverhalten führen:

An der Datenbank selbst:

  • Du hast Tabellen ohne primary key

Lösung: Achte darauf, dass jede Tabelle einen primary key auf der ID festgelegt hat. Das muss nicht zwingend er numerische Autoincrement sein, aber irgendeine Spalte gibt es doch immer, die als ID fungiert. Man kann den primary auch mehrere Spalten legen.

Auf der Java-Seite:

  • Du nutzt dieselbe Connection-Instanz von mehreren Threads aus gleichzeitig
  • Du managest diese Instanz selber
  • Du leakst Resourcen (nicht geschlossene Verbindungen, nicht geschlossene ResultSets usw.)
  • Du verwendest ResultSets aus Abfragen nach Schließen der Verbindung weiter. Verwende nicht das ResultSet als Daten weiter sondern fülle es, solange die Verbindung, aus der es kommt, noch offen ist, in ein Datenobjekt um und returne das staatdesen.

Nutze nicht den mysql-connector direkt, sondern verwende einen Connection-Pool (z.B. Apache dbcp2 oder Hikari).

Und am besten immer mit try-with-resources:

try (Connection connection = pool.getConnection()) {
	try (PreparedStatement stmt = connection.prepareStatement("INSERT INTO tabelle bla bla blubb...")) {
		stmt.setInt(1, id);
		stmt.setString(2, stringVariable);
		stmt.executeUpdate();
	}
} catch (SQLException ex) {
	//eat shit here xD
}


try (Connection connection = pool.getConnection()) {
	try (PreparedStatement stmt = connection.prepareStatement("SELECT bla bla bla")) {
		stmt.setInt(1, id);
		try (ResultSet set = stmt.executeQuery()) {
			//mach was mit dem Result
		}
	}
} catch (SQLException ex) {
	//eat shit here xD
}

Dadurch werden die Resourcen automatisch an den entsprechenden Stellen geschlossen. Auch dann, wenn es irgendwo mittendrin ne Exception schmeißt

Und so ein Pool ist nach der Erstellung sofort einsatzfähig und managed die Verbindungen im Hintergrund automatisch. Du musst dich um den Aufbau und um das Aufrechterhalten von Verbindungen nicht kümmern. Das macht der Pool.

Woher ich das weiß:Hobby – Ich beschäftige mich schon mehrere Jahre damit.

Dafür ist der Primärschlüssel da. Er identifiziert einen Datensatz. Wenn du ein INSERT() durchführst, vergibt entweder das DBMS oder du den Primärschlüssel.

Falls du ihn selbst vergibst, musst du vorher prüfen, ob er bereits existiert. Ansonsten sagt dir das DBMS, dass der Schlüssel bereits existiert und bricht den Commit ab.

Das ist alles, was man bei solch einer detaillierten Frage schreiben kann.