У моих поделок в таблице есть пять атрибутов, и если атрибут не существует, он будет 0
Я подозреваю, что вы делаете неправильныйПредположение и то, что вместо этого значение, вставленное, когда атрибут не существует, равно нулю, и определение столбцов атрибута с DEFAULT 0 может решить проблему
На это могут повлиять несколько факторов;
ОПРЕДЕЛЕНИЯ КОЛОННЫ
- У определений столбцов есть конкретное значение по умолчанию (ПО УМОЛЧАНИЮ 0) вместо значения по умолчанию ПО УМОЛЧАНИЮ, равного нулю.
МЕТОДОЛОГИЯ ВСТАВКИ
- Если значение не присвоено, пропускаете ли вы ЗНАЧЕНИЯ, не присвоенные
В противном случаеваш код работает до тех пор, пока не будет извлечено ни одной строки, когда вы получите android.database.CursorIndexOutOfBoundsException: индекс 0 запрошен, с размером 0 , потому что вы пытаетесь получить данные, когда в курсоре нет данных.
- т.е. вы перемещаете Курсор в первую строку, которая возвращает false (то есть, перемещение не сделано), когда строк нет, а затем проверяете, является ли Курсор нулевым.
- Курсор никогда не будет нулевым, если он возвращается из метода SQLiteDatabase, такого как rawQuery.
- Курсор всегда будет существовать и создавать его экземпляры (следовательно, не нуль) и быть действительным
- Курсор будет иметь счетчик строк (метод getCount () Cursor возвращает целое число числа строк вКурсор).
Ваш запрос работает, как ожидается, если неназначенные значения установлены в 0.
Следующий код: -
- Показывает, что, за исключением проблемы OutofBounds, ваш код и запрос, как показано, работают, если вставлены 0, а атрибуты пропущены, но если вставленные нули отсутствуют, это не так.
- Позволяет просматривать содержимоеТаблицы и значения NULL или 0
- Показывает разницу, которую делает использование DEFAULT 0, когда атрибуты опущены, а не установлены специально на 0.
- Используется вторая таблица, отличающаяся только тем, что DEFAULT 0закодировано в определениях столбцов атрибутов.
Databasehelper (с методами вставки и также методом dumpTable): -
public class DBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "mydb";
public static final int DBVERSION = 1;
public static final String TABLE_NAME = "mytable";
public static final String TABLE_NAME2 = "mytable2";
public static final String UID = "uid";
public static final String CNAME = "cname";
public static final String FIRST_ATTRIBUTE = "a1";
public static final String SECOND_ATTRIBUTE = "a2";
public static final String THIRD_ATTRIBUTE = "a3";
public static final String FOURTH_ATTRIBUTE = "a4";
public static final String FIFTH_ATTRIBUTE = "a5";
SQLiteDatabase mDB;
public DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
// Create both tables
@Override
public void onCreate(SQLiteDatabase db) {
String crt_tbl = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
UID + " INTEGER PRIMARY KEY," +
CNAME + " TEXT, " +
FIRST_ATTRIBUTE + " INTEGER, " +
SECOND_ATTRIBUTE + " INTEGER," +
THIRD_ATTRIBUTE + " INTEGER, " +
FOURTH_ATTRIBUTE + " INTEGER, " +
FIFTH_ATTRIBUTE + " INTEGER" +
")";
db.execSQL(crt_tbl);
String crt_tbl2 = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME2 + "(" +
UID + " INTEGER PRIMARY KEY," +
CNAME + " TEXT, " +
FIRST_ATTRIBUTE + " INTEGER DEFAULT 0, " +
SECOND_ATTRIBUTE + " INTEGER DEFAULT 0," +
THIRD_ATTRIBUTE + " INTEGER DEFAULT 0, " +
FOURTH_ATTRIBUTE + " INTEGER DEFAULT 0, " +
FIFTH_ATTRIBUTE + " INTEGER DEFAULT 0" +
")";
db.execSQL(crt_tbl2);
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
// Generic Insert method
public long insertRow(String table, String cname, int[] attributes) {
String[] attribute_columns = new String[]{FIRST_ATTRIBUTE,SECOND_ATTRIBUTE,THIRD_ATTRIBUTE,FOURTH_ATTRIBUTE,FIFTH_ATTRIBUTE};
ContentValues cv = new ContentValues();
cv.put(CNAME,cname);
for (int i=0; i < attributes.length; i++) {
cv.put(attribute_columns[i],attributes[i]);
}
return mDB.insert(table,null,cv);
}
// Insert row into table 1 with all 5 attributes
public long insertRow(String cname,int a1, int a2, int a3, int a4, int a5) {
int[] attributes = new int[]{a1,a2,a3,a4,a5};
return insertRow(TABLE_NAME,cname,attributes);
}
// Inert row in table 1 with first 2 attributes
public long insertRow(String cname, int a1, int a2) {
int[] attributes = new int[]{a1,a2};
return insertRow(TABLE_NAME,cname,attributes);
}
// Insert row into table 2 with all 5 atributes
public long insertRow2(String cname,int a1, int a2, int a3, int a4, int a5) {
int[] attributes = new int[]{a1,a2,a3,a4,a5};
return insertRow(TABLE_NAME2,cname,attributes);
}
// Insert row into table 2 with first 2 attributes
public long insertRow2(String cname, int a1, int a2) {
int[] attributes = new int[]{a1,a2};
return insertRow(TABLE_NAME2,cname,attributes);
}
public void dumpTableToLog(String table) {
Log.d("DUMPTABLE","Dumping table ==>" + table);
Cursor csr = mDB.query(table,null,null,null,null,null,null);
DatabaseUtils.dumpCursor(csr);
csr.close();
}
}
Операция вызова (MainActivity), включая ваши getData и альтернативный метод getData2: -
public class MainActivity extends AppCompatActivity {
DBHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new DBHelper(this);
//Example table 1 load data
dbHelper.getWritableDatabase().delete(DBHelper.TABLE_NAME,null,null); // Empty table
dbHelper.insertRow("Crafts", 2, 3, 0, 0, 0);
dbHelper.insertRow("Arts", 1, 1, 1, 1, 1);
dbHelper.insertRow("Science", 6, 3, 0, 0, 0);
dbHelper.insertRow("Maths", 2, 3, 0, 0, 0);
dbHelper.insertRow("Crafts2",2,3); //<<<<<<<<<< NULLS for a3-a5
dbHelper.dumpTableToLog(DBHelper.TABLE_NAME); // Dump all table 1 contents to the Log
Log.d("GETDATAREUSULT", getData(2, 3, 0, 0, 0));
Log.d("GETDATAREUSULT", getData(1, 3, 0, 0, 0));
//Example table 2 (with DEFAULT 0) (uses methods ending with 2)
dbHelper.getWritableDatabase().delete(DBHelper.TABLE_NAME,null,null); // Empty table
dbHelper.insertRow2("Crafts", 2, 3, 0, 0, 0);
dbHelper.insertRow2("Arts", 1, 1, 1, 1, 1);
dbHelper.insertRow2("Science", 6, 3, 0, 0, 0);
dbHelper.insertRow2("Maths", 2, 3, 0, 0, 0);
dbHelper.insertRow2("Crafts2",2,3); //<<<<<<<<<< NULLS for a3-a5
dbHelper.dumpTableToLog(DBHelper.TABLE_NAME2); // Dump all table 2 contents to the Log
Log.d("GETDATA2REUSULT", getData2(2, 3, 0, 0, 0));
Log.d("GETDATA2REUSULT", getData2(1, 3, 0, 0, 0));
}
// To get data from DB by querying the items selected
public String getData(int firstSelection, int secondSelection, int thirdSelection,
int fourthSelection, int fifthSelection) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
String firstSelectionStr, secondSelectionStr, thirdSelectionStr, fourthSelectionStr, fifthSelectionStr;
firstSelectionStr = Integer.toString(firstSelection);
secondSelectionStr = Integer.toString(secondSelection);
thirdSelectionStr = Integer.toString(thirdSelection);
fourthSelectionStr = Integer.toString(fourthSelection);
fifthSelectionStr = Integer.toString(fifthSelection);
//String[] columns = {DBHelper.UID,DBHelper.CNAME};
//Cursor cursor = db.query(DBHelper.TABLE_NAME,columns,null,null,null,null,null);
String selectQuery = "SELECT * FROM " + DBHelper.TABLE_NAME + " WHERE " + DBHelper.FIRST_ATTRIBUTE + "=? "
+ " AND " + DBHelper.SECOND_ATTRIBUTE + "=? " + " AND " + DBHelper.THIRD_ATTRIBUTE + "=? " + " AND " + DBHelper.FOURTH_ATTRIBUTE + "=? "
+ " AND " + DBHelper.FIFTH_ATTRIBUTE + "=?";
Cursor cursor = db.rawQuery(selectQuery, new String[]{firstSelectionStr, secondSelectionStr, thirdSelectionStr,
fourthSelectionStr, fifthSelectionStr});
StringBuilder buffer = new StringBuilder();
while (cursor.moveToNext()) {
buffer.append(cursor.getString(cursor.getColumnIndex(DBHelper.CNAME))).append(" ");
}
cursor.close(); //<<<<<<<<<< Should always close cursor when done with it.
/*
cursor.moveToFirst(); //<<<<<<<<<< SHOULD ALWAYS CHECK result of move false if unable true if able to move
if (cursor != null) { //<<<<<<<<<< A cursor return from SQLiteDatabase meyhod will never be null, useless/dangerous
int tresult = cursor.getCount();
// Append every data together
do {
//int cursorID = cursor.getInt(cursor.getColumnIndex(DBHelper.UID));
String chosenItem = cursor.getString(cursor.getColumnIndex(DBHelper.CNAME));
buffer.append(chosenItem + " ");
} while (cursor.moveToNext());
}
*/
/*while (cursor.moveToNext())
{
//int cursorID = cursor.getInt(cursor.getColumnIndex(DBHelper.UID));
String chosenItem = cursor.getString(cursor.getColumnIndex(DBHelper.CNAME));
buffer.append(chosenItem + " ");
}*/
return buffer.toString();
}
/**
* Alternative using the convenience query method
* @param firstSelection
* @param secondSelection
* @param thirdSelection
* @param fourthSelection
* @param fifthSelection
* @return
*/
public String getData2(int firstSelection, int secondSelection, int thirdSelection,
int fourthSelection, int fifthSelection) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
String whereclause = DBHelper.FIRST_ATTRIBUTE + "=? AND " +
DBHelper.SECOND_ATTRIBUTE + "=? AND " +
DBHelper.THIRD_ATTRIBUTE + "=? AND " +
DBHelper.FOURTH_ATTRIBUTE + "=? AND " +
DBHelper.FIFTH_ATTRIBUTE + "=?"
;
String[] whereargs = new String[]{
String.valueOf(firstSelection),
String.valueOf(secondSelection),
String.valueOf(thirdSelection),
String.valueOf(fourthSelection),
String.valueOf(fifthSelection)}
;
Cursor cursor = db.query(
DBHelper.TABLE_NAME2,
null,
whereclause,
whereargs,
null,null,null
);
StringBuilder buffer = new StringBuilder();
while (cursor.moveToNext()) {
buffer.append(cursor.getString(cursor.getColumnIndex(DBHelper.CNAME))).append(" ");
}
cursor.close(); //<<<<<<<<<< Should always close cursor when done with it.
return buffer.toString();
}
}
Результаты: -
Ниже приведен вывод в журнал
- Следует отметить, что в первой таблице ( без DEFAULT 0 ) не выбирается последняя строка ( Crafts2 ), в которой для последних трех заданы значения NULL.атрибуты согласно
D/GETDATAREUSULT: Crafts Maths
; - для второй таблицы ( с DEFAULT 0 ) последней строки (Crafts2 ) выбран в соответствии с
D/GETDATA2REUSULT: Crafts Maths Crafts2
В DumpTable показана эта последняя строка для первой таблицы (атрибуты 3-5 какnull)
12-01 01:09:12.140 1698-1698/? I/System.out: 4 {
12-01 01:09:12.140 1698-1698/? I/System.out: uid=5
12-01 01:09:12.140 1698-1698/? I/System.out: cname=Crafts2
12-01 01:09:12.140 1698-1698/? I/System.out: a1=2
12-01 01:09:12.140 1698-1698/? I/System.out: a2=3
12-01 01:09:12.140 1698-1698/? I/System.out: a3=null
12-01 01:09:12.140 1698-1698/? I/System.out: a4=null
12-01 01:09:12.140 1698-1698/? I/System.out: a5=null
12-01 01:09:12.140 1698-1698/? I/System.out: }
Для второго стола как
12-01 01:09:12.180 1698-1698/? I/System.out: 4 {
12-01 01:09:12.180 1698-1698/? I/System.out: uid=5
12-01 01:09:12.180 1698-1698/? I/System.out: cname=Crafts2
12-01 01:09:12.180 1698-1698/? I/System.out: a1=2
12-01 01:09:12.180 1698-1698/? I/System.out: a2=3
12-01 01:09:12.180 1698-1698/? I/System.out: a3=0
12-01 01:09:12.180 1698-1698/? I/System.out: a4=0
12-01 01:09:12.180 1698-1698/? I/System.out: a5=0
12-01 01:09:12.180 1698-1698/? I/System.out: }
: -
12-01 01:09:12.140 1698-1698/? D/DUMPTABLE: Dumping table ==>mytable
12-01 01:09:12.140 1698-1698/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@534b1f2c
12-01 01:09:12.140 1698-1698/? I/System.out: 0 {
12-01 01:09:12.140 1698-1698/? I/System.out: uid=1
12-01 01:09:12.140 1698-1698/? I/System.out: cname=Crafts
12-01 01:09:12.140 1698-1698/? I/System.out: a1=2
12-01 01:09:12.140 1698-1698/? I/System.out: a2=3
12-01 01:09:12.140 1698-1698/? I/System.out: a3=0
12-01 01:09:12.140 1698-1698/? I/System.out: a4=0
12-01 01:09:12.140 1698-1698/? I/System.out: a5=0
12-01 01:09:12.140 1698-1698/? I/System.out: }
12-01 01:09:12.140 1698-1698/? I/System.out: 1 {
12-01 01:09:12.140 1698-1698/? I/System.out: uid=2
12-01 01:09:12.140 1698-1698/? I/System.out: cname=Arts
12-01 01:09:12.140 1698-1698/? I/System.out: a1=1
12-01 01:09:12.140 1698-1698/? I/System.out: a2=1
12-01 01:09:12.140 1698-1698/? I/System.out: a3=1
12-01 01:09:12.140 1698-1698/? I/System.out: a4=1
12-01 01:09:12.140 1698-1698/? I/System.out: a5=1
12-01 01:09:12.140 1698-1698/? I/System.out: }
12-01 01:09:12.140 1698-1698/? I/System.out: 2 {
12-01 01:09:12.140 1698-1698/? I/System.out: uid=3
12-01 01:09:12.140 1698-1698/? I/System.out: cname=Science
12-01 01:09:12.140 1698-1698/? I/System.out: a1=6
12-01 01:09:12.140 1698-1698/? I/System.out: a2=3
12-01 01:09:12.140 1698-1698/? I/System.out: a3=0
12-01 01:09:12.140 1698-1698/? I/System.out: a4=0
12-01 01:09:12.140 1698-1698/? I/System.out: a5=0
12-01 01:09:12.140 1698-1698/? I/System.out: }
12-01 01:09:12.140 1698-1698/? I/System.out: 3 {
12-01 01:09:12.140 1698-1698/? I/System.out: uid=4
12-01 01:09:12.140 1698-1698/? I/System.out: cname=Maths
12-01 01:09:12.140 1698-1698/? I/System.out: a1=2
12-01 01:09:12.140 1698-1698/? I/System.out: a2=3
12-01 01:09:12.140 1698-1698/? I/System.out: a3=0
12-01 01:09:12.140 1698-1698/? I/System.out: a4=0
12-01 01:09:12.140 1698-1698/? I/System.out: a5=0
12-01 01:09:12.140 1698-1698/? I/System.out: }
12-01 01:09:12.140 1698-1698/? I/System.out: 4 {
12-01 01:09:12.140 1698-1698/? I/System.out: uid=5
12-01 01:09:12.140 1698-1698/? I/System.out: cname=Crafts2
12-01 01:09:12.140 1698-1698/? I/System.out: a1=2
12-01 01:09:12.140 1698-1698/? I/System.out: a2=3
12-01 01:09:12.140 1698-1698/? I/System.out: a3=null
12-01 01:09:12.140 1698-1698/? I/System.out: a4=null
12-01 01:09:12.140 1698-1698/? I/System.out: a5=null
12-01 01:09:12.140 1698-1698/? I/System.out: }
12-01 01:09:12.140 1698-1698/? I/System.out: <<<<<
12-01 01:09:12.144 1698-1698/? D/GETDATAREUSULT: Crafts Maths
12-01 01:09:12.176 1698-1698/? D/DUMPTABLE: Dumping table ==>mytable2
12-01 01:09:12.176 1698-1698/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@534a1c1c
12-01 01:09:12.180 1698-1698/? I/System.out: 0 {
12-01 01:09:12.180 1698-1698/? I/System.out: uid=1
12-01 01:09:12.180 1698-1698/? I/System.out: cname=Crafts
12-01 01:09:12.180 1698-1698/? I/System.out: a1=2
12-01 01:09:12.180 1698-1698/? I/System.out: a2=3
12-01 01:09:12.180 1698-1698/? I/System.out: a3=0
12-01 01:09:12.180 1698-1698/? I/System.out: a4=0
12-01 01:09:12.180 1698-1698/? I/System.out: a5=0
12-01 01:09:12.180 1698-1698/? I/System.out: }
12-01 01:09:12.180 1698-1698/? I/System.out: 1 {
12-01 01:09:12.180 1698-1698/? I/System.out: uid=2
12-01 01:09:12.180 1698-1698/? I/System.out: cname=Arts
12-01 01:09:12.180 1698-1698/? I/System.out: a1=1
12-01 01:09:12.180 1698-1698/? I/System.out: a2=1
12-01 01:09:12.180 1698-1698/? I/System.out: a3=1
12-01 01:09:12.180 1698-1698/? I/System.out: a4=1
12-01 01:09:12.180 1698-1698/? I/System.out: a5=1
12-01 01:09:12.180 1698-1698/? I/System.out: }
12-01 01:09:12.180 1698-1698/? I/System.out: 2 {
12-01 01:09:12.180 1698-1698/? I/System.out: uid=3
12-01 01:09:12.180 1698-1698/? I/System.out: cname=Science
12-01 01:09:12.180 1698-1698/? I/System.out: a1=6
12-01 01:09:12.180 1698-1698/? I/System.out: a2=3
12-01 01:09:12.180 1698-1698/? I/System.out: a3=0
12-01 01:09:12.180 1698-1698/? I/System.out: a4=0
12-01 01:09:12.180 1698-1698/? I/System.out: a5=0
12-01 01:09:12.180 1698-1698/? I/System.out: }
12-01 01:09:12.180 1698-1698/? I/System.out: 3 {
12-01 01:09:12.180 1698-1698/? I/System.out: uid=4
12-01 01:09:12.180 1698-1698/? I/System.out: cname=Maths
12-01 01:09:12.180 1698-1698/? I/System.out: a1=2
12-01 01:09:12.180 1698-1698/? I/System.out: a2=3
12-01 01:09:12.180 1698-1698/? I/System.out: a3=0
12-01 01:09:12.180 1698-1698/? I/System.out: a4=0
12-01 01:09:12.180 1698-1698/? I/System.out: a5=0
12-01 01:09:12.180 1698-1698/? I/System.out: }
12-01 01:09:12.180 1698-1698/? I/System.out: 4 {
12-01 01:09:12.180 1698-1698/? I/System.out: uid=5
12-01 01:09:12.180 1698-1698/? I/System.out: cname=Crafts2
12-01 01:09:12.180 1698-1698/? I/System.out: a1=2
12-01 01:09:12.180 1698-1698/? I/System.out: a2=3
12-01 01:09:12.180 1698-1698/? I/System.out: a3=0
12-01 01:09:12.180 1698-1698/? I/System.out: a4=0
12-01 01:09:12.180 1698-1698/? I/System.out: a5=0
12-01 01:09:12.180 1698-1698/? I/System.out: }
12-01 01:09:12.180 1698-1698/? I/System.out: <<<<<
12-01 01:09:12.184 1698-1698/? D/GETDATA2REUSULT: Crafts Maths Crafts2