您上面的代码将无法工作/无法按预期工作,原因是:-
首先,当您生成的游标名称为 mCursor 时,您尝试访问名称为 cursor 的游标。
您似乎正在访问以前创建/提取的游标,假设该游标中存在列 d,则该游标很可能具有列 d 的错误数据。
因此,代码应该是(仅用于纠正上述问题):-
String details = mCursor.getString(mCursor.getColumnIndex("d"));
然而,上述操作会失败,并出现
android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0
这是因为没有尝试移动到光标内的一行,因此光标位于“第一行之前”的位置(即位置 -1)。
要更正上述问题,您需要移动到有效行(如果有的话)。假设您将提取任意数量的行,那么您可以使用以下内容处理每一行:-
private void SO51603383() {
Cursor mCursor;
SO51603383DBHelper MyDbHelper = new SO51603383DBHelper(this);
mCursor = MyDbHelper.getReadableDatabase().rawQuery("select group_concat(b._id || ', ' || b.product_id || ', ' || b.no_of_units || ', ' || b.unit_price || ', ' || b.discount || ', ' || b.discount, '; ') as d,a.* \n" +
"from transactions a left join transactions b on a._id=b.local_ref_txn_id " +
"group by a._id", null);
while (mCursor.moveToNext()) {
String details = mCursor.getString(mCursor.getColumnIndex("d"));
}
}
当/如果您在使用 LEFT JOIN 时运行,您可能会得到空值,如下所示:-
如果连接操作符是“LEFT JOIN”或“LEFT OUTER JOIN”,那么在
ON 或 USING 过滤子句已被应用,额外的一行是
添加到原始左侧输入中每一行的输出
与复合数据集中完全不对应的数据集
(如果有的话)。添加的行在列中包含 NULL 值
通常包含从右侧输入数据集中复制的值。
SQL As Understood By SQLite - SELECT
所以你可能想改用 JOIN。
示例案例
使用以下作为数据库助手:-
public class SO51603383DBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "SO51603383.db";
public static final int DBVERSION = 1;
public static final String TB_TRANSACTIONS = "transactions";
public static final String COL_TRANSACTIONS_ID = BaseColumns._ID;
public static final String COl_TRANSACTIONS_NAME = "name";
public static final String COL_TRANSACTIONS_PRODUCTID = "product_id";
public static final String COL_TRANSACTIONS_NO_OF_UNITS = "no_of_units";
public static final String COL_TRANSACTIONS_UNIT_PRICE = "unit_price";
public static final String COL_TRANSACTIONS_DISCOUNT = "discount";
public static final String COl_TRANSACTIONS_LOCAL_REF_TXN = "local_ref_txn_id";
SQLiteDatabase mDB;
public SO51603383DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String crtsql = "CREATE TABLE IF NOT EXISTS " + TB_TRANSACTIONS + "(" +
COL_TRANSACTIONS_ID + " INTEGER PRIMARY KEY," +
COl_TRANSACTIONS_NAME + " TEXT," +
COL_TRANSACTIONS_PRODUCTID + " INTEGER, " +
COL_TRANSACTIONS_NO_OF_UNITS + " INTEGER, " +
COL_TRANSACTIONS_UNIT_PRICE + " INTEGER, " +
COL_TRANSACTIONS_DISCOUNT + " INTEGER, " +
COl_TRANSACTIONS_LOCAL_REF_TXN + " INTEGER" +
")";
db.execSQL(crtsql);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
public long add(String name, long productid, int units, int price, int discount, long localref) {
ContentValues cv = new ContentValues();
cv.put(COl_TRANSACTIONS_NAME,name);
cv.put(COL_TRANSACTIONS_PRODUCTID,productid);
cv.put(COL_TRANSACTIONS_NO_OF_UNITS,units);
cv.put(COL_TRANSACTIONS_UNIT_PRICE,price);
cv.put(COL_TRANSACTIONS_DISCOUNT,discount);
cv.put(COl_TRANSACTIONS_LOCAL_REF_TXN,localref);
return mDB.insert(TB_TRANSACTIONS,null,cv);
}
}
使用加载 2 行(参见上面的添加方法):-
MyDbHelper.add("Test001",1,10,22,3,0);
MyDbHelper.add("Test002",1,20,24,5,1);
然后运行:-
mCursor = MyDbHelper.getReadableDatabase().rawQuery(
"select group_concat(b._id || ', ' || b.product_id || ', ' || b.no_of_units || ', ' || b.unit_price || ', ' || b.discount || ', ' || b.discount, '; ') " +
"as d,a.* \n" +
"from transactions a left join transactions b on a._id=b.local_ref_txn_id " +
"group by a._id", null);
while (mCursor.moveToNext()) {
String details = mCursor.getString(mCursor.getColumnIndex("d"));
Log.d("DETAILS","Column D from query is :- " + details);
}
导致以下输出到日志(1 行数据,1 行空值):-
07-31 02:26:21.255 1580-1580/soanswers.soanswers D/DETAILS: Column D from query is :- 2, 1, 20, 24, 5, 5
Column D from query is :- null
改用:-
mCursor = MyDbHelper.getReadableDatabase().rawQuery(
"select group_concat(b._id || ', ' || b.product_id || ', ' || b.no_of_units || ', ' || b.unit_price || ', ' || b.discount || ', ' || b.discount, '; ') " +
"as d,a.* \n" +
//"from transactions a left join transactions b on a._id=b.local_ref_txn_id " +
"from transactions a join transactions b on a._id=b.local_ref_txn_id " +
"group by a._id", null);
while (mCursor.moveToNext()) {
String details = mCursor.getString(mCursor.getColumnIndex("d"));
Log.d("DETAILS","Column D from query is :- " + details);
}
导致(清除数据库后):-
07-31 05:56:38.872 2380-2380/soanswers.soanswers D/DETAILS: Column D from query is :- 2, 1, 20, 24, 5, 5
使用第一个代码 (LEFT JOIN) 并第二次运行,从而添加另外两行(除了 _id 值之外的重复),结果是:-
07-31 05:59:04.095 2440-2440/? D/DETAILS: Column D from query is :- 2, 1, 20, 24, 5, 5; 4, 1, 20, 24, 5, 5
Column D from query is :- null
Column D from query is :- null
Column D from query is :- null
使用第二个(只是加入)代码并运行两次,结果是:-
07-31 06:05:00.610 2565-2565/soanswers.soanswers D/DETAILS: Column D from query is :- 2, 1, 20, 24, 5, 5; 4, 1, 20, 24, 5, 5