รับรหัสที่สร้างขึ้นหลังจากการแทรก


138

ฉันใช้ SQLite กับ Android และฉันต้องการทราบวิธีที่ดีที่สุดในการสร้าง id ของแถวที่ฉันแทรก

วิธีแก้ปัญหาที่ฉันคิดว่าทำการค้นหาหลังจากรวม แต่ไม่ได้ดูวิธีที่ดีที่สุด

คำตอบ:


271

insertผลตอบแทนที่วิธีการidของแถวเพียงแทรกหรือ-1ถ้ามีข้อผิดพลาดระหว่างการแทรก

long id = db.insert(...);

SQLiteDatabaseที่เป็นฐานข้อมูล


21
ฉันอ่านสเป็ค "Return: ID แถวของแถวที่แทรกใหม่หรือ -1 หากเกิดข้อผิดพลาด" rowId เหมือนกับเขตข้อมูลที่ฉันสร้างขึ้น "id primary key autoincrement" หรือไม่
Marcos Vasconcelos

29
ใช่มันเหมือนกัน
แกรนด์

3
@GrAnd แต่ถ้าฉันจะลบแถว "เริ่มต้นกลาง" บางส่วนในตารางของฉันดังนั้นฉันจึงแบ่งลำดับแถว n-th ด้วย id = n ที่สร้างขึ้น รหัสแถวที่ส่งคืนจะยังคงเหมือนกันกับรหัสการสร้างอัตโนมัติหรือไม่
ทราบ Joe

1
จะทำอย่างไรถ้าคุณต้องการทำ INSERT หรือ UPDATE เพื่อรับ ID?
Timo

1
@ ไม่ทราบโจฉันรู้ว่านี่คือโพสต์เก่า แต่อาจเป็นประโยชน์สำหรับใครบางคน ID แถวและรหัสการรวมอัตโนมัติจะเหมือนกันแม้ว่าจะถูกลบออกจากตรงกลาง
Raj Kannan Iyyappan

8

หากใช้ ContentValues:

 DBHelper db =new DBHelper();// your dbHelper
 ContentValues values = new ContentValues();
  values.put("firstName","Ahmad");
 values.put("lastName","Aghazadeh");
 long insertedId= db.getSQLiteDatabase().insert("user", "", values) ;

หากแบบสอบถามใช้ exec select last_insert_rowid()

String sql = "INSERT INTO [user](firstName,lastName) VALUES (\"Ahmad\",\"Aghazadeh\"); select last_insert_rowid()";
 DBHelper itemType =new DBHelper();// your dbHelper
 c = db.rawQuery(sql, null);
 if (c.moveToFirst())
    result = c.getLong(0);

ถ้าใช้ห้อง

@Entity
class User {
    @PrimaryKey(autoGenerate = true)
    public int id;
    //...
}


@Dao
public interface UserDao{
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    long insert(User user);

    // Insert multiple users
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    long[] insert(User... user);
}

5

ฉันตรวจสอบแหล่งที่มา ฟังก์ชั่นinsertการใช้วิธีการsqlite3_last_insert_rowidเพื่อกลับ ID ตามเอกสารประกอบ: https://www.sqlite.org/c3ref/last_insert_rowid.html id แถวคือคอลัมน์ที่ซ่อนอยู่หรือคอลัมน์ประเภทหนึ่งINTEGER PRIMARY KEYหากมีการประกาศ

แต่ละรายการในตาราง SQLite ส่วนใหญ่ (ยกเว้นสำหรับWITHOUT ROWIDตาราง) มีคีย์เลขจำนวนเต็มแบบ 64 บิตที่ไม่ซ้ำกันซึ่งเรียกว่า " rowid " rowid มีอยู่เสมอในคอลัมน์ที่ไม่ได้ประกาศชื่อ ROWID, OID หรือ _ROWID_ ตราบใดที่ชื่อเหล่านั้นไม่ได้ถูกใช้โดยคอลัมน์ที่ประกาศอย่างชัดเจนเช่นกัน ถ้าตารางมีคอลัมน์ชนิดแล้วคอลัมน์ที่เป็นนามแฝงสำหรับ ROWIDINTEGER PRIMARY KEY

นั่นคือ_IDคอลัมน์เริ่มต้นโดยปกติ


1

ฉันมีปัญหาเล็กน้อยเกี่ยวกับเรื่องนี้ใน mySQL LAST_INSERT_ID ไม่ใช่วิธีที่เชื่อถือได้ในการรับ ID หากคุณมีผู้ใช้ตอกฐานข้อมูล ID ที่ส่งคืนอาจไม่ใช่ ID ที่แทรกโดยการสืบค้นที่คุณเรียกใช้หลาย ๆ ตัว ผู้ใช้รายอื่นอาจส่งผลกระทบต่อการส่งคืนรหัสนี้ เรามีเซิร์ฟเวอร์ที่มีผู้ใช้งานเฉลี่ย 7000 คนต่อนาทีและมันก็สะดุดเสมอ

วิธีแก้ปัญหาที่เราต้องใช้ข้อมูลจากแบบสอบถามที่คุณแทรกจากนั้นค้นหาผลลัพธ์นั้นโดยใช้ข้อมูลนั้น คุณกำลังส่งคำขอเพื่อค้นหารหัสล่าสุด ดังนั้นคุณอาจทำตาราง SELECT id จากที่ field = var และ field = var เพื่อรับ id มันมีประสิทธิภาพเล็กน้อยในการค้นหา แต่ผลลัพธ์ที่เชื่อถือได้กลับมามากขึ้น


3
สิ่งนี้ต้องการค่าคอลัมน์ของคุณสำหรับแต่ละแถวที่ไม่ซ้ำกัน (หรือส่วนใหญ่ไม่ซ้ำกัน) หรือความเสี่ยงกลับมาหลายรหัส
Richard Barker

0

หนึ่งก็จะได้รับแถวแทรกสุดท้าย _id last_insert_rowid()ใช้ โค้ดตัวอย่างมีดังต่อไปนี้

/**
 * Return Last inserted row id(auto incremented row) (_id)
 * @return
 */
public int getLastAddedRowId() {
    String queryLastRowInserted = "select last_insert_rowid()";

    final Cursor cursor = database.rawQuery(queryLastRowInserted, null);
    int _idLastInsertedRow = 0;
    if (cursor != null) {
        try {
            if (cursor.moveToFirst()) {
                _idLastInsertedRow = cursor.getInt(0);
            }
        } finally {
            cursor.close();
        }
    }

    return _idLastInsertedRow;

}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.