2016-07-23 13 views
0

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] 
+1

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). –

+0

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

+0

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

Antwort

1

Betrachten Sie eine Staging temporäre Tabelle mit dem Sie alle Daten anhängen, wie in eine ähnliche strukturierte Tabelle, ProductsTemp und dann auf Finaltisch wandern, Produkte, für die eindeutige Zeilen gefiltert. Im Folgenden sind die SQL-Anweisungen in Ihrem Java-Code in dieser Reihenfolge zu übernehmen:

Staging Anfügen (zwei Aussagen)

DELETE FROM ProductsTemp; 

INSERT INTO ProductsTemp VALUES (?,?,?,..,...); 

Schluss Migration

INSERT INTO Products (id, id2, raw_yn, ...) 
SELECT id, id2, raw_yn, ... 
FROM ProductsTemp temp 
WHERE NOT EXISTS (SELECT 1 FROM Products sub 
        WHERE sub.id = temp.id 
        AND sub.id2 = temp.id2 
        AND sub.raw_yn = temp.raw_yn); 
+0

Ich wollte Ihren Vorschlag vollständig testen, bevor ich Parfait kommentierte, danke für die Bereitstellung dieses. Ich konnte die letzte Abfrage nicht ausführen, da ich so lange Werte in den INSERT- und SELECT-Abfragen hatte, dass die Syntaxfehler, die ich bekam, schwer zu debuggen waren. Ich habe viel über temporäre Tabellen gelesen, und ich habe vor, es für die Zukunft zu behalten. Deine Lösung funktioniert wahrscheinlich, aber Gord's Vorschläge haben mich zufriedengestellt. Ich habe dich für deine Zeit/deinen Beitrag +1. Vielen Dank. – Mathomatic

Verwandte Themen