Sqlite:SqliteDatabase.delete()与原始查询

问题描述:

结论: Android的数据库API 工作但文档是严重不完整的。Sqlite:SqliteDatabase.delete()与原始查询


我最近由于灵活性SQLite的提供了不强迫你创建表时指定数据类型运行到大脑失事情况。问题是我的思维模式假设每个数据类型都是一个通用字符序列(如果没有指定),因此与数据库交谈的方式是通过java.lang.String

但是,你可别怪我要么当你看到类似下面的方法:

int delete (String table, 
       String whereClause, 
       String[] whereArgs) 
SqlDatabase

Android docs

我有一个表,包括联系电话(我存储为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团队提供?

+0

您可以包括用于'delete'的实际代码的 – MikeT

SQLite支持multiple data types;尽管列类型没有严格执行,但在某些情况下可能会自动转换值(这称为affinity)。

当您的值存储为数字时,您应该将它们作为数字访问,而不是字符串。

Android数据库API不允许在大多数函数中使用字符串以外的参数类型。这是一个可怕的设计错误。

要搜索一个号码,或者使用execSQL(),它允许你使用数量的参数,或者转换成字符串值回一个数字:

db.delete(..., "timestamp = CAST(? AS NUMBER)", 
      new String[]{ String.valueOf(ts) }); 
+0

好样的!这解决了问题。这为我探索更多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(); 
      } 
     }