2009-09-03 9 views
48

Gibt es eine Möglichkeit, den automatisch generierten Schlüssel aus einer DB-Abfrage abzurufen, wenn eine Java-Abfrage mit vorbereiteten Anweisungen verwendet wird.Gibt es eine Möglichkeit, die Autoinkrement-ID aus einer vorbereiteten Anweisung abzurufen

Zum Beispiel kann ich AutoGeneratedKeys wie folgt arbeiten.

stmt = conn.createStatement(); 

stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS); 
if(returnLastInsertId) { 
    ResultSet rs = stmt.getGeneratedKeys(); 
    rs.next(); 
    auto_id = rs.getInt(1); 
} 

Jedoch. Was, wenn ich eine Einfügung mit einer vorbereiteten Aussage machen möchte.

String sql = "INSERT INTO table (column1, column2) values(?, ?)"; 
stmt = conn.prepareStatement(sql); 

//this is an error 
stmt.executeUpdate(Statement.RETURN_GENERATED_KEYS); 
if(returnLastInsertId) { 
    //this is an error since the above is an error 
    ResultSet rs = stmt.getGeneratedKeys(); 
    rs.next(); 
    auto_id = rs.getInt(1); 
} 

Gibt es eine Möglichkeit, dies zu tun, über die ich nicht weiß. Es scheint aus dem Javadoc, dass PreparedStatements die Auto Generated ID nicht zurückgeben kann.

+0

returnLastInsertId wo bekommen Sie diese Variable – dedpo

Antwort

84

Ja. Siehe here. Abschnitt 7.1.9. Ändern Sie Ihren Code in:

String sql = "INSERT INTO table (column1, column2) values(?, ?)"; 
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); 


stmt.executeUpdate(); 
if(returnLastInsertId) { 
    ResultSet rs = stmt.getGeneratedKeys(); 
    rs.next(); 
    auto_id = rs.getInt(1); 
} 
+0

Dies funktioniert nicht von Oracle. –

+8

@JafarAli, diese Frage bezieht sich auf mysql. In Oracle müssen Sie [die generierte Spalte] (https://community.oracle.com/thread/338591) angeben oder die Zeilen-ID verwenden. – Yishai

+1

Hast du 'rs.close()' vergessen? Ist es nötig ? – Winter

2

Ja, es gibt einen Weg. Ich habe das gerade im Java-Dokument gefunden.

Sie ist Weg, um die AutoGeneratedKeys id passieren wie

folgt
String sql = "INSERT INTO table (column1, column2) values(?, ?)"; 
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); 
3

Es gibt ein paar Möglichkeiten, und es scheint, verschiedene JDBC-Treiber behandelt die Dinge ein bisschen anders, oder gar nicht in einigen Fällen (einige werden nur geben Sie Primärschlüssel automatisch generiert, nicht anderen Spalten), aber die Grundformen sind

stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); 

Oder verwenden Sie dieses Formular:

String autogenColumns[] = {"column1","column2"}; 
stmt = conn.prepareStatement(sql, autogenColumns) 
1

Ich bin einer von denen, die durch ein paar Threads surften, auf der Suche nach einer Lösung für dieses Problem ... und es endlich zum Laufen bringen. FÜR DIE VERWENDUNG jdbc: oracle: thin: mit ojdbc6.jar BITTE BERÜCKSICHTIGEN SIE: Sie entweder Methoden verwenden: (Methode 1)

Try{ 
    String yourSQL="insert into Table1(Id,Col2,Col3) values(SEQ.nextval,?,?)"; 
    myPrepStatement = <Connection>.prepareStatement(yourSQL, Statement.RETURN_GENERATED_KEYS); 
    myPrepStatement.setInt(1, 123); 
    myPrepStatement.setInt(2, 123); 

    myPrepStatement.executeUpdate(); 
    ResultSet rs = getGeneratedKeys; 
    if(rs.next()) { 
     java.sql.RowId rid=rs.getRowId(1); 
     //what you get is only a RowId ref, try make use of it anyway U could think of 
     System.out.println(rid); 
    } 
} catch (SQLException e) { 
    // 
} 

(Methode 2)

Try{ 
    String yourSQL="insert into Table1(Id,Col2,Col3) values(SEQ.nextval,?,?)"; 
    //IMPORTANT: here's where other threads don tell U, you need to list ALL cols 
    //mentioned in your query in the array 
    myPrepStatement = <Connection>.prepareStatement(yourSQL, new String[]{"Id","Col2","Col3"}); 
    myPrepStatement.setInt(1, 123); 
    myPrepStatement.setInt(2, 123); 
    myPrepStatement.executeUpdate(); 
    ResultSet rs = getGeneratedKeys; 
    if(rs.next()) { 
    //In this exp, the autoKey val is in 1st col 
    int id=rs.getLong(1); 
    //now this's a real value of col Id 
    System.out.println(id); 
    } 
} catch (SQLException e) { 
    // 
} 

Grundsätzlich versuchen nicht verwendet Methode1, wenn Sie nur den Wert von SEQ.Nextval, b'cse geben Sie nur die RowID Ref, dass Sie knacken Ihren Kopf finden Weg, um es zu nutzen, die auch passen alle Datentyp, den Sie versucht haben, es zu werfen! Dies funktioniert möglicherweise in MySQL, DB2, aber nicht in Oracle.

AND, schalten Sie Ihren SQL Developer, Toad oder jeden anderen Client aus, der dieselbe Anmeldesitzung verwendet, um INSERT beim Debuggen auszuführen. Es darf dich nicht jedes Mal beeinflussen (Debugging-Aufruf) ... bis du feststellst, dass deine Apps für einige Zeit ausnahmslos stehen bleiben. Ja ... halt ohne Ausnahme!

+0

'executeUpdate()' gibt kein 'ResultSet' zurück, es gibt ein' int' zurück, das die Anzahl der Aktualisierungen angibt. Sie müssen die generierten Schlüssel separat abrufen. Sehen Sie die vorhandenen Antworten und den Javadoc um Himmels Willen. -1. [Nochmals] (http://stackoverflow.com/questions/14844864/jdbc-preparedstatement-always-returns-1-as-auto-generated-key) Bitte hören Sie hier auf, ungeprüftes Ratespiel zu veröffentlichen. – EJP

+0

Entschuldigung, mein Fehler. Ich habe sie korrigiert. – peterong

-1
Connection connection=null; 
    int generatedkey=0; 
    PreparedStatement pstmt=connection.prepareStatement("Your insert query"); 
    ResultSet rs=pstmt.getGeneratedKeys(); 
    if (rs.next()) { 
     generatedkey=rs.getInt(1); 
       System.out.println("Auto Generated Primary Key " + generatedkey); 
    } 
Verwandte Themen