Advertisement
Guest User

Untitled

a guest
Aug 17th, 2017
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.66 KB | None | 0 0
  1. UserCharge imoney为double类型:
  2. cursor.getText() 和 cursor.getDouble()效果不能保证为一致!
  3. getText()方法可能丢失精度,getDouble()方法结果正确
  4.  
  5.  
  6. UserCharge imoney 为 text类型:
  7. 查询cursor.getText() 和 cursor.getDouble()效果一致!而且text类型并不影响sql对字段查询统计求和等操作
  8.  
  9. 而且由于cursor代码是系统代码无法修改,ORM 将UserCharge的imoney字段改为String 或者 BigDecimal都只是按text读取,反而用double能保证读取结果正确
  10.  
  11. 因此,sql查询结果中所有列为text可以保证结果正确
  12. 或者cursor获取数字列采用getDouble也可以保证结果正确
  13.  
  14. 有个简单办法,强行将表中所有字段改为text类型存储,这样不管按text读字段还是double读字段都没问题。
  15. sqlite不允许改字段类型,旧版本数据库升级的时候,变相改字段类型方法有下面2种:
  16. 1.可以先创建一个临时表,再删除原表,将临时表表名改为原表表名
  17. 比如:
  18. create table tmp_charge as select * from bk_user_charge;
  19. drop table bk_user_charge;
  20. alter table tmp_charge rename to bk_user_charge;
  21. 这种会丢失主键外键索引等一堆信息
  22. 2.将数据复制到临时表,再删除原表,创建新的字段为text的表(同时处理好主键外键等信息),将临时表数据copy过来。这个需要处理所有字段,sql类似上面的,只是更麻烦
  23.  
  24. 跑通代码一看,统计查询结果仍然不精确!
  25. 因为即使imoney字段为text,如果sql中做了运算,比如sum(imoney),则这列结果又会变成double
  26. cursor.getText()很有可能又会丢失精度了,这种方式走不通。
  27.  
  28.  
  29. 根据上面分析,解决问题方法有2种,一种是金额全部按double读取,一种是将查询结果字段改为text
  30.  
  31. 1、按double读取,OrmLite提供的queryRaw()查询方法需要制定DataType 对金额的字段指定为DataType.DOUBLE,其它指定为DataType.STRING即可。
  32. 然而,queryRaw有个方法是指定RawRowMapper,这个本来是为了简便操作,可以直接将查询结果映射为java对象的。可是这个方法默认获取字段全为getString()
  33. 需要指定其DataType,这映射对象就没有一点方便性了。。。因此,下边的方案更好用
  34. 2、将查询结果中数字字段强行转为text类型!根据上面的分析,这样不管采用getText()还是getDouble()都没问题了。将结果强制转换为text类型有2种方法,一种是采用sqlite 的cast方法,另一种简单,类似于java将数字转为字符串,将数字拼接一个字符串即可
  35. select cast(uc.imoney as text) as imoney from bk_user_charge;
  36. select uc.imoney || '' as imoney from bk_user_charge;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement