为什么即使项目存在且属性正确,我的光标仍为空?

时间:2018-11-29 22:43:43

标签: java android sqlite android-sqlite

所以我一直在尝试查询表中的某些项目,但是什么也没有返回。我知道我的表中只有3个项目,但是我的选择是有效的属性,因此我可以得到一些东西。

我的工艺品在表上有五个属性,如果一个属性不存在,则在表中将为0。我正在做这样的查询:“工艺品必须有2,3,0,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();

        cursor.moveToFirst();

        if (cursor != null) {

            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();
    }

1 个答案:

答案 0 :(得分:0)

  

我在表中的手工艺品上有五个属性,如果   属性不存在,将为0

我怀疑您可能做出了错误的假设,而是当属性不存在时插入的值为null,并且使用DEFAULT 0定义属性列可能会解决此问题 < / p>

有一些因素可能会影响这一点;

  • 列定义

    • 列定义是否具有特定的默认值(DEFAULT 0),而不是默认的DEFAULT值null。
  • 插入方法论

    • 未分配值时,您会跳过未分配的值

否则,除非获得 android.database.CursorIndexOutOfBoundsException:请求索引,且大小为0 ,否则未提取任何行,否则代码将正常工作,因为您尝试在没有数据时获取数据在光标中。

  • 即您将Cursor移至第一行,如果没有行,则返回false(即未移动),然后检查Cursor是否为null。
  • 从SQLiteDatabase方法(例如rawQuery)返回的Cursor永远不会为null。
    • 光标将始终存在并被实例化(因此不为null)并且有效
    • Cursor将具有行计数(Cursor getCount()方法返回Cursor中行数的整数)。

如果未分配的值设置为0,您的查询将按预期工作。

以下代码:-

  • 除OutofBounds问题外,它表明您的代码和查询在插入0和省略属性的情况下有效,但在插入null时无效。
  • 允许您查看表的内容以及是否为null或0
  • 显示了使用DEFAULT 0时(省略属性)与将其专门设置为0的区别。
  • 使用第二个表,仅在属性列定义中编码了DEFAULT 0之外。

数据库帮助器(具有插入方法以及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();
    }
}

结果:-

以下是日志的输出

  • 请注意,第一个表不带默认值0 )不会选择最后一行(),最后三个属性,按照 D/GETDATAREUSULT: Crafts Maths ;
  • 第二张表具有DEFAULT 0 )的同时,根据 {}选择了最后一行(){ {1}}
  • DumpTable显示第一个表的最后一行(属性3-5 为空)

    D/GETDATA2REUSULT: Crafts Maths Crafts2

  • 对于第二张表,按

    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: }