كيفية الحصول على قيمة من الماضي إدراج الصف ؟ [مكررة]

StackOverflow https://stackoverflow.com/questions/241003

سؤال

هذا السؤال سبق الجواب هنا:

هل هناك طريقة للحصول على قيمة من الماضي إدراج الصف ؟

انا إدراج صف واحد حيث PK تلقائيا زيادة وأود أن الحصول على هذا PK.فقط PK هو ضمان أن تكون فريدة من نوعها في الجدول.

أنا باستخدام جافا مع JDBC و كيو.

هل كانت مفيدة؟

المحلول

باستخدام PostgreSQL، يمكنك القيام بذلك عبر الكلمة الأساسية RETURNING:

PostgresSQL - العودة

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

نصائح أخرى

راجع مستندات API لـ java.sql.Statement.

في الأساس، عندما تتصل executeUpdate() أو executeQuery(), ، استخدم ال Statement.RETURN_GENERATED_KEYS ثابت.يمكنك بعد ذلك الاتصال getGeneratedKeys للحصول على المفاتيح التي تم إنشاؤها تلقائيًا لجميع الصفوف التي تم إنشاؤها بواسطة هذا التنفيذ.(على افتراض أن برنامج تشغيل JDBC الخاص بك يوفر ذلك.)

يذهب شيء على غرار هذا:

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

إذا كنت تستخدم 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);
}

منذ إصدار برنامج تشغيل PostgreSQL JDBC 8.4-701 ال PreparedStatement#getGeneratedKeys() أخيرًا يعمل بكامل طاقته.نحن نستخدمه هنا لمدة عام تقريبًا في الإنتاج لتحقيق رضانا الكامل.

في "JDBC عادي" PreparedStatement يجب إنشاؤه على النحو التالي حتى يتمكن من إرجاع المفاتيح:

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

يمكنك تنزيل إصدار برنامج تشغيل JDBC الحالي هنا (وهو في الوقت الحالي لا يزال 8.4-701).

تسلسل في كيو يتم المعاملة آمنة.بحيث يمكنك استخدام

currval(sequence)

اقتباس:

currval

إرجاع القيمة الأكثر التي تم الحصول عليها مؤخرا من قبل nextval على هذا التسلسل في الدورة الحالية.(خطأ ذكرت إذا nextval أبدا ودعا هذا التسلسل في هذا الدورة.) لاحظ أن لأن هذا هو تعود الدورة القيمة المحلية ، يعطي يمكن التنبؤ بها الإجابة حتى إذا غيرها من الدورات المنفذة nextval وفي الوقت نفسه.

إليك كيفية حل المشكلة، بناءً على الإجابات هنا:

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

إذا كنت تستخدم 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);

استخدم التسلسلات في postgres لأعمدة المعرف:

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

SELECT currval('MySequence');

سيعيد currval القيمة الحالية للتسلسل في نفس الجلسة.

(في MS SQL، يمكنك استخدام @@identity أو 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();

لا تستخدم SELECT currval('MySequence') - تتم زيادة القيمة عند الإدخالات التي تفشل.

بالنسبة إلى MyBatis 3.0.4 مع التعليقات التوضيحية وبرنامج تشغيل Postgresql 9.0-801.jdbc4، يمكنك تحديد طريقة واجهة في مخطط الخرائط الخاص بك مثل

public interface ObjectiveMapper {

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

لاحظ أنه يتم استخدام @Select بدلاً من @Insert.

على سبيل المثال:

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

مع ,Statement.RETURN_GENERATED_KEYS);" لم يوجد.

استخدم هذا الكود البسيط:

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

إذا كنت في معاملة يمكنك استخدامها SELECT lastval() بعد الإدراج للحصول على آخر معرف تم إنشاؤه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top