Ich habe eine H2 Datenbank mit dem Namen PRODUCTS
, mit 5000 Zeilen und 55 Spalten pro Zeile. Ich verwende derzeit eine PreparedStatement
, um der Datenbank Zeilen mit Werten hinzuzufügen, aber es prüft nicht, ob die Zeile bereits existiert. Stattdessen muss ich nur die Zeile einfügen, wenn der Spaltenname "ID" (Typ VARCHAR) nicht enthält eine bestimmte alphanumerische Zeichenfolge, und wenn der Spaltenname "ID2" (Typ VARCHAR) nicht eine bestimmte alphanumerische Zeichenfolge, und wenn der Spaltenname "raw_yn" (Typ BOOLEAN) false
enthält. Die Werte, die ich in die vorbereitete Anweisung eingeben, werden über eine Methode bereitgestellt.In Tabelle einfügen, wenn bestimmte Werte nicht vorhanden sind
Die Frage here ist sehr nah an dem, was ich frage, mit dem Unterschied, dass es solution basiert auf das Hinzufügen von Zeilen zu einem leeren DB, und stellt sicher, dass die Datenbank leer ist. Der Schöpfer von H2 kommentierte sagen:
Dann wird die „wo nicht existiert“ sichergestellt Zeilen nur, wenn die Tabelle eingefügt [TABELLE] leer ist.
Wie passe ich diesen Code, so dass es nur die INSERT-Abfrage, wenn meine über 3 Anforderungen erfüllt erfüllt sind (auch nicht DB leer ist)?
Zur Zeit habe ich:
import java.sql. *;
static final String JDBC_DRIVER = "org.h2.Driver";
static final String DB_URL = "jdbc:h2:~/myDB";
static final String USER = "test";
static final String PASS = "test";
static final Connection conn = null;
static final Statement stmt = null;
public class DataBaseManager {
public void insertIntoDB(String id1val, String id2val, Boolean raw_yn_val, ...,...) {
try {
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(DB_URL, USER, PASS);
myStatement = "INSERT INTO PRODUCTS VALUES(?,?,?,..,...)";
stmt = conn.prepareStatement(myStatement);
stmt.setString(1, id1val);
stmt.setString(2, id2val);
stmt.setBoolean(3, raw_yn_val);
stmt.setString(4,....);
// Continue up to 55
stmt.executeUpdate();
}
[catch&finally blocks]
}
}
Was soll myStatement
geändert werden? Ich bin verwirrt, denn wenn ich select 0, 'id1' union
wie unten verwende, wie passt das in meine PreparedStatement
von stmt.setString(1, id1val);
??. Danke für Ihre Hilfe.
INSERT INTO PRODUCTS SELECT * FROM(
select 0, 'id1' union // <--- How does this fit into Prepared Statement?
select 1, 'id2' union
select 2, 'raw_yn' union
) x where not exists(SELECT * FROM PRODUCTS); // <--- Ensures only works when empty
UPDATE:
Gord Vorschlag folgend, habe ich zusammen den folgenden Code setzen. Wenn die Datenbank leer ist, gibt n
0 zurück. Dies dauert ca. 1 Minute, um der leeren Datenbank 5000 Zeilen hinzuzufügen. Wenn es jedoch eine Übereinstimmung gibt, dauert es fast 5x länger, obwohl ich nur return
im Gegensatz zur Verwendung von zusätzlichen INSERT
Code verwende. Also sollte es nicht schneller sein?
try {
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(DB_URL, USER, PASS);
statement = conn.createStatement();
String sql = "SELECT COUNT(*) AS n FROM PROPERTIES WHERE id1='" + id1 + "' AND id2='" + id2 + "' AND raw_yn='true'";
rs = statement.executeQuery(sql);
rs.next();
if (rs.getInt("n") == 0) {
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(DB_URL, USER, PASS);
myStatement = "INSERT INTO PROPERTIES VALUES(?,?,?,...)";
stmt = conn.prepareStatement(myStatement);
stmt.setString(1, id1);
stmt.setString(2, id2);
stmt.setBoolean(3, raw_yn);
stmt.executeUpdate();
} else {
return; // <-- Takes 5x longer to go through ???
}
}
[catch & finally blocks]
Da es so aussieht, Sie Einfügen wird die Zeilen einzeln nacheinander, vielleicht kann Ihre 'insertIntoDB'-Methode eine' SELECT COUNT (*) ASn VON PRODUCTS WHERE ... 'ausführen, um zu bestimmen, ob die erforderliche Zeile bereits existiert, und dann nur die 'INSERT'-Anweisung ausführen nicht (dh wenn die Zeile von 'SEL ECT ist Null). –
Sie sollten eine Staging-Temp-Tabelle (* ProductsTemp *) verwenden, um dann zur endgültigen * Produkte * pro Zeilenprüfung zu migrieren. Die Überprüfung von 55 Werten kann jedoch mühsam sein oder wollten Sie nur ID, ID2 und RAW_YN prüfen? – Parfait
Danke Gord, ich melde mich wieder. Aber zuerst, wie erhalte ich den tatsächlichen 'int' Wert des' n'? Wenn ich 'String sql =" SELECT COUNT (*) AS n VON EIGENSCHAFTEN ID = '"+ id1val +"' "; rs = statement.executeQuery (sql); 'Ich habe nur eine Ergebnismenge, aber wie kann ich auf' n' zugreifen, um die Anzahl zu erhalten? @Parfait, ich muss nur ID, ID2 und Raw_yn für jede mögliche Zeileneinfügung überprüfen. Können Sie ein Beispiel für Ihre mögliche Lösung geben? Ich arbeite jetzt an Gord's. Danke – Mathomatic