【问题标题】:How to make AUTO_INCREMENT on Android SQLite database?如何在 Android SQLite 数据库上创建 AUTO_INCREMENT?
【发布时间】:2010-12-08 14:18:33
【问题描述】:

嘿,我想创建一个带有 AUTO_INCREMENT 列的数据库。但我不知道如何解析方法插入中的值。我只是不知道将什么解析为 AUTO_INCREMENT 参数,我解析了应该是 auto_increment 的 1,但我知道它不应该解析。

这里是 CallDatHelper.java 类,我在其中声明方法 insert 和创建数据库的方法。

package com.psyhclo;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

public class CallDataHelper {

private static final String DATABASE_NAME = "calls.db";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "contact_data";

private Context context;
private SQLiteDatabase db;

public CallDataHelper(Context context) {
    this.context = context;
    OpenHelper openHelper = new OpenHelper(this.context);
    this.db = openHelper.getWritableDatabase();
}

public boolean insert(Integer cId, String cName, String numType,
        String cNum, String dur, String date, String currTime) {
    this.db.execSQL("insert into "
            + TABLE_NAME
            + "(id, contact_id, contact_name, number_type, contact_number, duration, date, current_time, cont) "
            + "values( ? ," + cId + ", " + cName + ", " + numType + ", "
            + cNum + ", " + dur + ", " + date + ", " + currTime + ", ? )");
    return true;        
}

public void atualiza(String word) {
    this.db.execSQL("UPDATE words SET cont = cont + 1 WHERE (word= ?)",
            new String[] { word });
}

public void deleteAll() {
    this.db.delete(TABLE_NAME, null, null);
}

public boolean select(String wrd) {

    String word;
    Cursor cursor = this.db.query(TABLE_NAME, new String[] { "word" },
            "word like ?", new String[] { wrd }, null, null, null);
    if (cursor.moveToFirst()) {
        do {
            word = cursor.getString(0);
        } while (cursor.moveToNext());
    }
    if (cursor != null && !cursor.isClosed()) {
        cursor.close();
        return true;
    } else {
        return false;
    }
}

public List<String> selectAll() {
    List<String> list = new ArrayList<String>();
    Cursor cursor = this.db.query(TABLE_NAME, new String[] { "word" },
            null, null, null, null, "cont desc");
    if (cursor.moveToFirst()) {
        do {
            list.add(cursor.getString(0).toUpperCase());
        } while (cursor.moveToNext());
    }
    if (cursor != null && !cursor.isClosed()) {
        cursor.close();
    }
    return list;
}

private static class OpenHelper extends SQLiteOpenHelper {

    OpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE "
                + TABLE_NAME
                + "(id INTEGER PRIMARY KEY AUTOINCREMENT, contact_id INTEGER, contact_name VARCHAR(50), number_type VARCHAR(50), contact_number VARCHAR(50), duration TIME, date DATE, current_time TIME, cont INTEGER)");

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w("RatedCalls Database",
                "Upgrading database, this will drop tables and recreate.");
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }
}
}

这里是我调用 insert 方法解析我想要插入的数据的地方。

this.dh.insert(1 , 1, contactName, numType, contactNumber,
                    duration, callDate, currTime);

【问题讨论】:

  • 让我在这里做一个安全说明:像这样手动构建 SQL 查询肯定会被黑客入侵。如果攻击者决定任何这些参数的值,则可以完全修改查询。在此处查看更多信息:en.wikipedia.org/wiki/SQL_injection

标签: android sqlite


【解决方案1】:

您不必像在 MYSQL 中那样专门写 AUTO_INCREMENT

只需要将主键字段定义为_id INTEGER PRIMARY KEY

如果在创建表时用INT 定义了主键字段,它将不起作用。应该是INTEGER,就是这样。

当你在插入记录时没有为主键字段传递任何值时,它会自动将该值增加为唯一值(与MYSQLAUTO_INCREMENT工作方式相同)

【讨论】:

  • 问题中似乎没有提到 MySQL。
  • 我认为 JibW 只是与 MySQL 进行比较以更好地解释事情。
  • 哈哈,那是我的问题。我将其声明为 INT ;) 谢谢。
  • 只是为了说明为什么应该避免使用 AUTO_INCREMENT 语句。 The AUTOINCREMENT keyword imposes extra CPU, memory, disk space, and disk I/O overhead and should be avoided if not strictly needed. It is usually not needed.sqlite.org/autoinc.html。使用 INTEGER PRIMARY KEY 就足够了。
  • AUTOINCREMENT 如果你想避免在数据库的生命周期内重复使用ROWIDs,应该使用。 i.e the purpose of AUTOINCREMENT is to prevent the reuse of ROWIDs from previously deleted rows.
【解决方案2】:

您不必解析任何内容。如果该列创建为AUTOINCREMENT,则只需传递其他值:

db.execSQL("insert into "
        + TABLE_NAME
        + "(contact_id, contact_name, number_type, contact_number, duration, date, current_time, cont) "
        + "values( "+ cId + ", " + cName + ", " + numType + ", "
        + cNum + ", " + dur + ", " + date + ", " + currTime + ", ? )");

顺便说一句,总是推荐使用Android的insert方法插入数据:

ContentValues values = new ContentValues();
values.put("contact_id", cId);
values.put("contact_name", cName);
// etc.
db.insert(TABLE_NAME, null, values);

【讨论】:

  • 但是如何在另一个类中实现呢?更好的是,如何在另一个类上调用这个方法,只引用它并解析正确的参数?
  • 嗯……你已经有办法了,就用它吧……有什么问题?
  • 我说,db.insert方法一定要在Activity上调用吧?但是为了调用这个方法,我需要启动对象 db,它是一个 SQLiteDatabase 对象。但是如何在活动中启动它?我的意思是,私有 SQLiteDatabase db = 'what???'。
  • 你已经有一个CallDataHelper 类,不是吗?只需:CallDataHelper blah = new CallDataHelper(YourActivity.this); blah.insert(blah blah);
【解决方案3】:
this.db.insert(NULL , 1, contactName, numType, contactNumber,
                    duration, callDate, currTime);

【讨论】:

  • Java 中没有 NULL 关键字。
【解决方案4】:
final static String Database_name="empDb.db";

public DatabaseHelper(Context context) {
    super(context, Database_name, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("create table emp_tbl (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT,salary TEXT)");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS tbl_emp");
}

获取更多信息 https://www.youtube.com/watch?v=W8-Z85oPNmQ

博客:https://itmulc.blogspot.com/2016/08/android-sqlite-database-with-complete.html

【讨论】:

    【解决方案5】:
    this.db.insert(null , 1, contactName, numType, contactNumber,
                    duration, callDate, currTime);
    

    使用 java null 而不是 SQL NULL

    【讨论】:

    • 嗨。这与问题无关,您似乎正在纠正一个非常古老且不相关的答案;这应该是对它的评论。
    猜你喜欢
    • 2023-03-25
    • 2018-06-23
    • 2023-04-03
    • 1970-01-01
    • 2017-12-19
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    • 2015-07-04
    相关资源
    最近更新 更多