无法写入导入的 SQLite 数据库 Android
Posted
技术标签:
【中文标题】无法写入导入的 SQLite 数据库 Android【英文标题】:Can't write to imported SQLite database Android 【发布时间】:2021-10-06 17:52:12 【问题描述】:我已将一个现有数据库导入我的应用程序的assets/databases
文件夹。问题是我无法写入或截断表 (DETELE FROM
) - 只能读取。另外,我没有遇到任何异常。
我正在使用从其父活动传递给构造函数的上下文从适配器调用DatabaseAccess
。
(我可以看到在androidStudio的Database Inspector中打开了数据库)
DatabaseOpenHelper.java
public class DatabaseOpenHelper extends SQLiteAssetHelper
private static final String DATABASE_NAME = "Products.db";
private static final int DATABASE_VERSION = 1;
public DatabaseOpenHelper(Context context)
super(context, DATABASE_NAME, null, DATABASE_VERSION);
DatabaseAccess.java:
public class DatabaseAccess
private SQLiteOpenHelper openHelper;
private SQLiteDatabase database;
private static DatabaseAccess instance;
private DatabaseAccess(Context context)
this.openHelper = new DatabaseOpenHelper(context);
public static DatabaseAccess getInstance(Context context)
if (instance == null)
instance = new DatabaseAccess(context);
return instance;
public void openDatabase()
this.database = openHelper.getWritableDatabase();
public SQLiteDatabase getWritableDatabase()
return openHelper.getWritableDatabase();
public SQLiteDatabase getReadableDatabase()
return openHelper.getReadableDatabase();
public void closeDatabase()
if (database != null)
this.database.close();
public void insert(CartItem item)
try
String query = String.format(Locale.ENGLISH,"INSERT INTO main.CART_CONTENT (ITEM_DESCRIPTION, PRODUCER, UNIT_PRICE, QUANTITY) VALUES (\"%s\", \"%s\", %.2f, %.2f);",
item.getName(),
item.getProducer(),
item.getUnit_price(),
item.getQuantity());
if(database != null)
database.rawQuery(query, null);
catch (Exception e)
e.printStackTrace();
public CartItem checkForProduct(CartItem item)
String query = "SELECT * FROM main.CART_CONTENT " +
"WHERE ITEM_DESCRIPTION = \"%s\" AND PRODUCER = \"%s\"";
query = String.format(Locale.ENGLISH, query, item.getName(), item.getProducer());
Cursor cursor = getReadableDatabase().rawQuery(query, null);
CartItem updatedItem = new CartItem();
if (cursor.getCount() != 0)
cursor.moveToFirst();
updatedItem = new CartItem(
cursor.getString(1),
cursor.getString(2),
Double.parseDouble(cursor.getString(3) + item.getUnit_price()),
Double.parseDouble(cursor.getString(4)) + item.getQuantity());
cursor.close();
insert(updatedItem);
return updatedItem;
else
insert(item);
return item;
public void emptyDatabase()
try
database.rawQuery("DELETE FROM CART_CONTENT", null).close();
database.rawQuery("DELETE FROM sqlite_sequence WHERE name='CART_CONTENT';", null).close();
catch (Exception e)
e.printStackTrace();
【问题讨论】:
【参考方案1】:另外,我没有遇到任何异常。
那是因为你在 try .... catch 中捕获异常,这是不推荐用于 SQLite 访问的东西(因为它隐藏了诸如语法错误之类的错误)。我建议如果您查看日志,您会发现被捕获的异常。
插入肯定会出现问题,因为它似乎忽略了:-
字符串常量由单引号(')括起来。字符串中的单引号可以通过将两个单引号放在一行中进行编码 - 就像在 Pascal 中一样。 不支持使用反斜杠字符的 C 样式转义,因为它们不是标准 SQL。 SQLite SQL Language Expressions - 3. Literal Values (Constants)
我建议使用 SQLiteDatabase 便捷方法而不是 rawQuery 方法。这些构建底层 SQL,绑定值。
参见insert(注意insertOrThrow 和insertOnConflict)和delete所以或许可以考虑将 DatabaseAccess 中的 insert
和 emptyDatabase
方法替换为:-
public long insert(CartItem item)
ContentValues cv = new ContentValues();
cv.put("ITEM_DESCRIPTION",item.getName());
cv.put("PRODUCER",item.getProducer());
cv.put("UNIT_PRICE",item.getUnit_price());
cv.put("QUANTITY",item.getQuantity());
return database.insert("CART_CONTENT",null,cv);
public int emptyDatabase()
int rv;
database.beginTransaction();
rv = database.delete("CART_CONTENT",null,null);
database.delete("sqlite_sequence","name=?",new String[]"CART_CONTENT");
database.setTransactionSuccessful();
database.endTransaction();
return rv;
注意插入是INSERT OR IGNORE
insert
返回插入行的 rowid(也就是具有 AUTOINCREMENT 编码的列,因此是 rowid 列的别名)
附注AUTOINCREMENT 很有可能只是在浪费资源 - 请参阅 SQLiteAutoincrement。但是,请注意,如果排除 AUTOINCREMENT,则不需要从 sqlite_sequenece 中删除该行,如果 CART_CONTENT 是唯一具有 AUTOINCREMENT 的表,则会导致找不到表失败。
emptyDatabase
返回从 CART_CONTENT 表中删除的行数。
有意省略了 try .... catch 块/子句。 SO上的很多SQLite问题因为使用了try .... catch而没有实现。
beginTransaction、setTransctionSuccessful、endTransaction 不是必需的,如果省略 AUTOINCREMENT,也没有任何用处。
请注意以上代码为in-principal code,尚未编译或运行,可能包含小错误
【讨论】:
以上是关于无法写入导入的 SQLite 数据库 Android的主要内容,如果未能解决你的问题,请参考以下文章