web-dev-qa-db-ja.com

最後に挿入された行から値を取得する方法は?

最後に挿入された行から値を取得する方法はありますか?

PKが自動的に増加する行を挿入していますが、このPKを取得したいと思います。 PKのみがテーブル内で一意であることが保証されています。

JDBCとPostgreSQLでJavaを使用しています。

51
eflles

PostgreSQLでは、RETURNINGキーワードを介してそれを行うことができます。

PostgresSQL-RETURNING

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

「anyfield」の値を返します。 「anyfield」はシーケンスでもそうでなくてもかまいません。

JDBCで使用するには、次のようにします。

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

Java.sql.Statement のAPIドキュメントを参照してください。

基本的に、executeUpdate()またはexecuteQuery()を呼び出すときは、Statement.RETURN_GENERATED_KEYS定数。その後、getGeneratedKeysを呼び出して、その実行によって作成されたすべての行の自動生成キーを取得できます。 (JDBCドライバーが提供すると仮定します。)

これに沿って何かを行います:

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

JDBC 3.0を使用している場合は、挿入するとすぐにPKの値を取得できます。

方法について説明する記事を次に示します。 https://www.ibm.com/developerworks/Java/library/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);
}
16
anjanb

PostgreSQL JDBCドライバーバージョン 8.4-701 以降、 PreparedStatement#getGeneratedKeys() が完全に機能するようになりました。私たちはここでほぼ1年、生産に使用しています。

「プレーンJDBC」では、PreparedStatementを次のように作成して、キーを返すようにする必要があります。

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

現在のJDBCドライバーのバージョンをダウンロードできます here (現時点では8.4-701です)。

11
BalusC

Postgresqlのシーケンスはトランザクションセーフです。だから、使用することができます

currval(sequence)

引用:

通貨

現在のセッションでこのシーケンスのnextvalによって最後に取得された値を返します。 (このセッションでこのシーケンスに対してnextvalが一度も呼び出されていない場合はエラーが報告されます。)これはセッションローカル値を返すため、他のセッションがnextvalを実行している場合でも予測可能な答えを与えることに注意してください。

8
svrist

ここでの答えに基づいて、私はそれをどのように解決したのですか:

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));
        }
7
eflles

Statementを使用している場合は、次を探してください。

//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);

PreparedStatementを使用している場合は、次を探してください。

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);
4
Priyadharshani

ID列にpostgresのシーケンスを使用します。

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

SELECT currval('MySequence');

currvalは、同じセッションのシーケンスの現在の値を返します。

(MS SQLでは、@@ identityまたはSCOPE_IDENTITY()を使用します)

1
BradC
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();
1

MyBatis 3.0.4 with AnnotationsおよびPostgresql driver 9.0-801.jdbc4の場合、マッパーで次のようなインターフェースメソッドを定義します。

public interface ObjectiveMapper {

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

@Insertの代わりに@Selectが使用されることに注意してください。

0
emicklei

SELECT currval( 'MySequence')を使用しないでください-失敗した挿入で値が増加します。

0
smilek

トランザクションを使用している場合、挿入後にSELECT lastval()を使用して、最後に生成されたIDを取得できます。

0
mihu86

例えば:

接続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 =(整数)rs.getInt(1); 
 pais.setId(id); 
} 
} 

,Statement.RETURN_GENERATED_KEYS);" 見つかりません。

0
fernando

その単純なコードを使用します。

// 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)
0
danigonlinea