Sqlite:SqliteDatabase.delete()与原始查询
结论: Android的数据库API 工作但文档是严重不完整的。Sqlite:SqliteDatabase.delete()与原始查询
我最近由于灵活性SQLite的提供了不强迫你创建表时指定数据类型运行到大脑失事情况。问题是我的思维模式假设每个数据类型都是一个通用字符序列(如果没有指定),因此与数据库交谈的方式是通过java.lang.String
。
但是,你可别怪我要么当你看到类似下面的方法:
int delete (String table,
String whereClause,
String[] whereArgs)
在
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";
电话号码不是问题;这是插入/删除中创建问题的时间戳
所以,我尝试运行一个原始删除查询,删除了引号(需要使用字符串/ varchar类型),并且它成功删除。我用这个下面的方法:
db.execSQL(String sql, Object[] whereArgs)
这里要注意的关键一点是,相比于delete()
时Object[]
是String[]
不同。我传递了一个Long对象来使它工作,但在delete()
中传递Long.toString()
似乎没用。
所以我的问题是,我的分析是正确的,并delete()
API基本上是无用的或有我错过了picture..after都有些大,它是由精心Android团队提供?
SQLite支持multiple data types;尽管列类型没有严格执行,但在某些情况下可能会自动转换值(这称为affinity)。
当您的值存储为数字时,您应该将它们作为数字访问,而不是字符串。
Android数据库API不允许在大多数函数中使用字符串以外的参数类型。这是一个可怕的设计错误。
要搜索一个号码,或者使用execSQL()
,它允许你使用数量的参数,或者转换成字符串值回一个数字:
db.delete(..., "timestamp = CAST(? AS NUMBER)",
new String[]{ String.valueOf(ts) });
好样的!这解决了问题。这为我探索更多SQlite警告提供了动力。不能相信我在这件事上浪费了一天的时间。谢谢。 –
的问题是我的心态,假设每个数据类型将是 一般的字符序列,如果没有指定,因此,办法 聊到数据库是通过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();
}
}
您可以包括用于'delete'的实际代码的 – MikeT