结论: Android的数据库API 工作但文档非常不完整。
由于Sqlite提供的灵活性,我最近遇到了大脑破坏的情况,因为在创建表时不强制您指定数据类型。我的心态是假设每个数据类型都是一般字符序列(如果没有指定),因此与数据库通信的方式是java.lang.String
。
但是当你看到如下方法时,你不能怪我:
int delete (String table,
String whereClause,
String[] whereArgs)
来自Android docs的SqlDatabase
课程中的。
我的表格包含电话号码(我存储为java.lang.String
)和时间戳作为长字段。当我尝试使用这种方法删除记录时,尽管进行了无数的调试,它仍然没有被删除。
我检查了所有内容并且查询没有问题,表格存在且所有清单都是偶然的,我发现在以原始方式查询而不是使用上述方法时删除时间戳周围的''会产生成功删除,像这样:
DELETE FROM messages_records_table WHERE messageTimestamp = 1508494606000;
而不是以下内容:
DELETE FROM messages_records_table WHERE messageTimestamp = '1508494606000';
,或者
DELETE FROM messages_records_table WHERE messageTimestamp = "1508494606000";
电话号码不是问题;这是在INSERTION / DELETION
中创建问题的时间戳因此,我尝试运行原始删除查询,删除了引号(字符串/ varchar类型需要),并且它成功删除。我使用了以下方法:
db.execSQL(String sql, Object[] whereArgs)
此处需要注意的关键是,与Object[]
相比,String[]
与delete()
不同。我传递了一个Long to Object来使其工作,但在Long.toString()
中传递delete()
似乎毫无用处。
所以我的问题是,我的分析是否正确,delete()
API基本没用,或者我错过了一些更大的图片......毕竟,它是由Android团队提供的吗?
答案 0 :(得分:1)
SQLite支持multiple data types;虽然没有严格执行列类型,但在某些情况下可能会自动转换值(这称为affinity)。
当您的值存储为数字时,您应该以数字形式访问它们,而不是字符串。
Android数据库API不允许您在大多数函数中使用字符串以外的参数类型。这是一个可怕的设计错误。
要搜索数字,请使用execSQL()
(允许您使用数字参数)或将字符串值转换回数字:
db.delete(..., "timestamp = CAST(? AS NUMBER)",
new String[]{ String.valueOf(ts) });
答案 1 :(得分:0)
问题是我的心态假设每种数据类型都是 一般字符序列,如果没有指定,因此的方式 与数据库交谈是通过java.lang.String。
我认为这是真正的问题。
如果您没有指定类型,例如
CREATE TABLE mytable (col1,col2,col3)
然后根据Determination of Column Affinity(3.1)规则3: -
3)如果列的声明类型包含字符串" BLOB"或者如果没有 指定了类型,然后该列具有关联BLOB。
然后根据第3节
具有亲和力BLOB的列不喜欢一个存储类 另一个并没有尝试强制来自一个存储类的数据 到另一个。
我个人从未遇到过删除问题。但是我确实总是根据rowid删除。
以下是一个实际工作示例用法,显示 delete
没有用,并且正在删除很长时间。但是列的类型都是INTEGER: -
int pudeletes;
int sldeletes;
int rdeletes;
int pdeletes;
if(doesProductExist(productid)) {
// if not in a transaction then begin a transaction
if(!intransaction) {
db.beginTransaction();
}
String whereargs[] = { Long.toString(productid)};
// Delete ProductUsage rows that use this product
pudeletes = db.delete(
DBProductusageTableConstants.PRODUCTUSAGE_TABLE,
DBProductusageTableConstants.PRODUCTUSAGE_PRODUCTREF_COL +
" = ?",
whereargs
);
// Delete ShopList rows that use this product
sldeletes = db.delete(
DBShopListTableConstants.SHOPLIST_TABLE,
DBShopListTableConstants.SHOPLIST_PRODUCTREF_COL +
" = ?",
whereargs
);
// Delete Rules rows that use this product
rdeletes = db.delete(
DBRulesTableConstants.RULES_TABLE,
DBRulesTableConstants.RULES_PRODUCTREF_COL +
" = ?",
whereargs
);
// Delete the Product
pdeletes = db.delete(
DBProductsTableConstants.PRODUCTS_TABLE,
DBProductsTableConstants.PRODUCTS_ID_COL +
" = ?",
whereargs
);
// if originally not in a transaction then as one was started
// complete and end the transaction
if(!intransaction) {
db.setTransactionSuccessful();
db.endTransaction();
}
}