【问题标题】:Android SQLite negative values with ORDER BY带有 ORDER BY 的 Android SQLite 负值
【发布时间】:2011-01-30 20:10:26
【问题描述】:

我有一个非常基本的情况:

我有一个大约 5k 行的表格:

CREATE TABLE "words" ("id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL , "name" TEXT NOT NULL , "def" TEXT NOT NULL, "rand" INTEGER)

我使用“UPDATE words SET rand=random()”定期更新

在 android 中,当我使用 rawQuery() 创建游标时,使用以下内容:

SELECT w.id, w.name, w.def, w.rand FROM words w ORDER BY w.rand ASC;

返回的游标没有以正确的顺序迭代。例如。它将按以下顺序输出具有 rand 值的列:

-1298882092
-2138143484
-1115732861
118839193
...

有人知道这里发生了什么吗?这不应该工作吗?如果我在 SQLiteManager 中运行完全相同的查询,它会以正确的顺序返回结果,所以这似乎是 android/cursor 特定的。

更新:

这是android中的代码,我尝试了多种方法:

尝试 1:

Cursor cursor = db.rawQuery("SELECT w.id, w.name, w.def, w.rand FROM words w ORDER BY w.rand ASC", new String[]{});

尝试 2:

Cursor cursor = db.query("words", new String[]{"id", "name", "def", "rand"},
            null, null, null, null, "rand ASC");

在这两种情况下,我都会像下面这样迭代:

while(cursor.moveToNext()) {
    ...
    Log.i("Test", cursor.getInt(3));
    ...
}

【问题讨论】:

  • 不适用于 Android,但它似乎在这里工作:ideone.com/GEnG3
  • 是的,它也适用于 sqlitemanager,所以我认为它是特定于 android 的。实际案例也有 5k 行和 rand 列上的索引。
  • 能贴出安卓代码吗?
  • 在问题中添加了代码。
  • 您多久更新一次 rand 列?您确定这不是问题的根源吗?

标签: android sql sqlite android-cursor


【解决方案1】:

我解决了,只是一个简单的疏忽。 random() 函数返回一个可以大于 java int 数据类型的值。这正在产生溢出。切换到 getLong() 一切正常。光标一直在正确迭代。

【讨论】:

  • 很好地解决了这个问题。静默的 int 截断错误很难调试
【解决方案2】:

我在使用 android cursor、rawquery 和 group by 时遇到了问题。结果未排序。

这是桌子:

public static final String I_ID = "iid";
public static final String I_QID = "qid";
public static final String I_STATUS = "status";
public static final String I_PDATE = "pub_date";
public static final String I_TYPE = "tipo";
public static final String I_TITLE = "titolo";
public static final String I_LINK = "link";
public static final String I_QR = "qrcode";
public static final String I_DESC = "descrizione";

private static final String C_ITEM_T = 
        "CREATE TABLE \""+T_ITEM+"\" ("+
        "\""+I_ID+"\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"+
        "\""+I_QID+"\" INTEGER NOT NULL REFERENCES "+T_QUERY+"("+Q_ID+") ,"+
        "\""+I_STATUS+"\" INTEGER NOT NULL,"+
        "\""+I_PDATE+"\" TEXT NOT NULL,"+
        "\""+I_TYPE+"\" TEXT NOT NULL,"+
        "\""+I_TITLE+"\" TEXT NOT NULL,"+
        "\""+I_LINK+"\" TEXT UNIQUE NOT NULL,"+
        "\""+I_QR+"\" TEXT UNIQUE NOT NULL,"+
        "\""+I_DESC+"\" TEXT"+
        ");";

public static final String A_ID = "aid";
public static final String A_IID = "iid";
public static final String A_SIZE = "grandezza";
public static final String A_DURATION = "durata";
public static final String A_CHANNELS = "canali";
public static final String A_RATE = "sampleRate";
public static final String A_TORRENT = "torrent";
public static final String A_DOWNLOAD = "download";
public static final String A_LICENSE_URL = "licenza_url";
public static final String A_TAGS = "tags";
public static final String A_CREATOR = "creatore";

private static final String C_ATTR_T = 
        "CREATE TABLE \""+T_ATTR+"\" ("+
        "\""+A_ID+"\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"+
        "\""+A_IID+"\" INTEGER NOT NULL REFERENCES "+T_ITEM+"("+I_ID+") ,"+
        "\""+A_SIZE+"\" LONG NOT NULL,"+
        "\""+A_DURATION+"\" LONG NOT NULL,"+
        "\""+A_CHANNELS+"\" TEXT NOT NULL,"+
        "\""+A_RATE+"\" TEXT NOT NULL,"+
        "\""+A_TORRENT+"\" TEXT NOT NULL,"+
        "\""+A_DOWNLOAD+"\" TEXT NOT NULL,"+
        "\""+A_LICENSE_URL+"\"TEXT,"+
        "\""+A_TAGS+"\" TEXT,"+
        "\""+A_CREATOR+"\" TEXT,"+
        "UNIQUE ("+A_ID+","+A_IID+")"+
        ");";

这是我的查询:

public static final String FILL_GRID = "SELECT * "+
        "FROM "+ Db.T_ITEM + " i " +
        "LEFT OUTER JOIN "+Db.T_ATTR+" a ON ( i."+Db.I_ID+"=a."+Db.A_IID+ ")"+ 
        " WHERE i."+Db.I_QID+" = ? AND i."+Db.I_STATUS+" <> "+Db.STATUS_DELETED +
                    " GROUP BY ? ";

这里是我如何使用它:

Cursor c = db.rawQuery(FILL_GRID, new String[]{String.valueOf(qid), order});

我确定 qid 是一个整数,并订购 i.titolo ASC 或 DESC

对我有用的唯一解决方法是在 rawquery 调用方法中修改通过 clausole 移动组的查询:

public static final String FILL_GRID = "SELECT * "+
        "FROM "+ Db.T_ITEM + " i " +
        "LEFT OUTER JOIN "+Db.T_ATTR+" a ON ( i."+Db.I_ID+"=a."+Db.A_IID+ ")"+ 
        " WHERE i."+Db.I_QID+" = ? AND i."+Db.I_STATUS+" <> "+Db.STATUS_DELETED;

Cursor c = db.rawQuery(FILL_GRID + " ORDER BY " + order, new String[]{String.valueOf(qid)});

【讨论】:

    猜你喜欢
    • 2015-06-28
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多