Pergunta

Esta questão já tem uma resposta aqui:

Existe alguma maneira de obter um valor a partir da última linha inserida?

Eu estou inserindo uma linha onde a PK aumentará automaticamente, e eu gostaria de obter este PK. Apenas o PK é garantido para ser único na tabela.

Eu estou usando Java com um JDBC e PostgreSQL.

Foi útil?

Solução

Com PostgreSQL você pode fazê-lo através da palavra-chave RETORNO:

PostgresSQL - RETORNO

INSERT INTO mytable( field_1, field_2,... )
VALUES ( value_1, value_2 ) RETURNING anyfield

Ele irá retornar o valor de "anyfield". "Anyfield" pode ser uma seqüência ou não.

Para usá-lo com JDBC, fazer:

ResultSet rs = statement.executeQuery("INSERT ... RETURNING ID");
rs.next();
rs.getInt(1);

Outras dicas

Veja a documentação da API para java.sql.Statement .

Basicamente, quando você chamar executeUpdate() ou executeQuery(), use a constante Statement.RETURN_GENERATED_KEYS. Você pode então chamar getGeneratedKeys para obter as chaves geradas automaticamente de todas as linhas criadas por essa execução. (Assumindo que o seu driver JDBC fornece-lo.)

É algo ao longo das linhas deste:

Statement stmt = conn.createStatement();
stmt.execute(sql, Statement.RETURN_GENERATED_KEYS);
ResultSet keyset = stmt.getGeneratedKeys();

Se você estiver usando JDBC 3.0, então você pode obter o valor do PK assim que você inseriu.

Aqui está um artigo que fala sobre como: https://www.ibm .com / developerworks / java / biblioteca / j-jdbcnew /

Statement stmt = conn.createStatement();
// Obtain the generated key that results from the query.
stmt.executeUpdate("INSERT INTO authors " +
                   "(first_name, last_name) " +
                   "VALUES ('George', 'Orwell')",
                   Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
if ( rs.next() ) {
    // Retrieve the auto generated key(s).
    int key = rs.getInt(1);
}

Desde PostgreSQL JDBC versão do driver 8,4-701 o PreparedStatement#getGeneratedKeys() é finalmente totalmente funcional. Vamos utilizá-lo aqui quase um ano de produção para a nossa plena satisfação.

Em "JDBC simples" as necessidades PreparedStatement a ser criado da seguinte forma para torná-lo para devolver as chaves:

statement = connection.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS);

Você pode baixar a versão atual driver JDBC aqui (que é no momento ainda 8,4-701).

As seqüências no PostgreSQL são seguros transação. Então você pode usar o

currval(sequence)

Citação:

currval

retornar o valor obtido mais recentemente por nextval para esta seqüência na sessão atual. (Um erro é relatado se nextval nunca foi chamado para esta sequência neste sessão.) Note que, porque esta é retornar um valor de sessão local, dá uma resposta previsível, mesmo se outras sessões estão executando nextval enquanto isso.

Aqui está como eu resolveu, com base nas respostas aqui:

Connection conn = ConnectToDB(); //ConnectToDB establishes a connection to the database.
String sql = "INSERT INTO \"TableName\"" +
        "(\"Column1\", \"Column2\",\"Column3\",\"Column4\")" +
        "VALUES ('value1',value2, 'value3', 'value4') RETURNING 
         \"TableName\".\"TableId\"";
PreparedStatement prpState = conn.prepareStatement(sql);
ResultSet rs = prpState.executeQuery();
if(rs.next()){
      System.out.println(rs.getInt(1));
        }

Se você estiver usando Statement, vá para o seguinte

//MY_NUMBER is the column name in the database 
String generatedColumns[] = {"MY_NUMBER"};
Statement stmt = conn.createStatement();

//String sql holds the insert query
stmt.executeUpdate(sql, generatedColumns);

ResultSet rs = stmt.getGeneratedKeys();

// The generated id

if(rs.next())
long key = rs.getLong(1);

Se você estiver usando PreparedStatement, vá para o seguinte

String generatedColumns[] = {"MY_NUMBER"};
PreparedStatement pstmt = conn.prepareStatement(sql,generatedColumns);
pstmt.setString(1, "qwerty");

pstmt.execute();
ResultSet rs = pstmt.getGeneratedKeys();
if(rs.next())
long key = rs.getLong(1);

Use seqüências em postgres para colunas id:

INSERT mytable(myid) VALUES (nextval('MySequence'));

SELECT currval('MySequence');

currval irá retornar o valor atual da seqüência na mesma sessão.

(Em MS SQL, você usaria @@ identidade ou SCOPE_IDENTITY ())

PreparedStatement stmt = getConnection(PROJECTDB + 2)
    .prepareStatement("INSERT INTO fonts (font_size) VALUES(?) RETURNING fonts.*");
stmt.setString(1, "986");
ResultSet res = stmt.executeQuery();
while (res.next()) {
    System.out.println("Generated key: " + res.getLong(1));
    System.out.println("Generated key: " + res.getInt(2));
    System.out.println("Generated key: " + res.getInt(3));
}
stmt.close();

Não use currval SELECIONAR ( 'MySequence') -. O valor é incrementado em inserções que falham

Para MyBatis 3.0.4 com anotações e PostgreSQL motorista 9.0-801.jdbc4 você define um método de interface em sua Mapper como

public interface ObjectiveMapper {

@Select("insert into objectives" +
        " (code,title,description) values" +
        " (#{code}, #{title}, #{description}) returning id")
int insert(Objective anObjective);

Note que @Seleccione é usado em vez de @Insert.

Por exemplo:

 Connection conn = null;
            PreparedStatement sth = null;
            ResultSet rs =null;
            try {
                conn = delegate.getConnection();
                sth = conn.prepareStatement(INSERT_SQL);
                sth.setString(1, pais.getNombre());
                sth.executeUpdate();
                rs=sth.getGeneratedKeys();
                if(rs.next()){
                    Integer id = (Integer) rs.getInt(1);
                    pais.setId(id);
                }
            } 

com ,Statement.RETURN_GENERATED_KEYS);" não encontrado.

Use esse código simples:

// Do your insert code

myDataBase.execSQL("INSERT INTO TABLE_NAME (FIELD_NAME1,FIELD_NAME2,...)VALUES (VALUE1,VALUE2,...)");

// Use the sqlite function "last_insert_rowid"

Cursor last_id_inserted = yourBD.rawQuery("SELECT last_insert_rowid()", null);

// Retrieve data from cursor.

last_id_inserted.moveToFirst(); // Don't forget that!

ultimo_id = last_id_inserted.getLong(0);  // For Java, the result is returned on Long type  (64)

Se você estiver em uma transação que você pode usar SELECT lastval() após uma inserção para obter o último ID gerado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top