Android:无法从包含1行1列的CursorWindow读取第0行第-1列

时间:2014-01-28 20:23:48

标签: java android database sqlite cursor

在下面的代码中,getLatestCorrect()和getLatestIncorrect()方法都会导致错误并捕获异常。我在StackOverflow上查看了一些类似的问题,发现没有我认为适用于这种情况的解决方案。

ManipulateDatabase类的LogCat输出和(相关)代码清单(包含上面提到的两个问题方法)。

logcat的

01-28 19:50:31.204: I/System.out(535): BUTTON CLICKED!
01-28 19:50:31.204: I/System.out(535): Inside case 2
01-28 19:50:31.216: I/System.out(535): Words in input: 22
01-28 19:50:31.216: I/System.out(535): Words in ideal: 15
01-28 19:50:31.216: I/System.out(535): Input: Harper Lee call us to do what is right and face the consequences - as she has done with the whole novel
01-28 19:50:31.216: I/System.out(535):  Ideal: Courage is portrayed as persistence where defeat is inevitable instead of heroic and bold actions
01-28 19:50:31.216: I/System.out(535): A match has been found for:is
01-28 19:50:31.216: I/System.out(535): A match has been found for:as
01-28 19:50:31.224: I/System.out(535): A match has been found for:is
01-28 19:50:31.224: I/System.out(535): A match has been found for:and
01-28 19:50:31.224: I/System.out(535): 11
01-28 19:50:31.224: I/System.out(535): 11
01-28 19:50:31.224: I/System.out(535): 19
01-28 19:50:31.224: I/System.out(535): 73
01-28 19:50:31.224: I/System.out(535): 121
01-28 19:50:31.234: I/System.out(535): similarLength
01-28 19:50:31.324: E/CursorWindow(535): Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 1 columns.
01-28 19:50:31.354: I/System.out(535): Caught excption from getLastCorrect
01-28 19:50:31.354: E/CursorWindow(535): Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 1 columns.
01-28 19:50:31.384: I/System.out(535): Caught exception from getLastIncorrect

ManipulateDatabase代码

/**
 * Contains SQL statements and manages connections
 * 
 * @author Daniel Lawson
 * @version 29/12/13
 */
package com.lawson.englishlitrevision;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.AssetManager;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Scanner;
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

public class ManipulateDatabase {

    /** String representing the name of the database */
    private static final String databaseName = "EnglishDatabase.db";

    /** Int representing the current version of the database */
    private static final int databaseVersion = 113;

    // ----------------------------------------------------------------------------------

    /**
     * String representing the table that stores the name of the piece and
     * whether it is a play or not.
     */
    private static final String pieceTable = "pieceTable";

    /**
     * String representing the table that stores the name of the point made,
     * which piece it belongs to, and which element it pertains to.
     */

    private static final String specificTable = "specificTable";

    /**
     * String representing the table that stores the element, the piece it
     * belongs to, and whether or not it is a character.
     */

    private static final String elementTable = "elementTable";

    /**
     * String representing the table that stores the quote and the point it
     * links to.
     */

    private static final String quoteTable = "quoteTable";

    /**
     * String representing the table that stores the piece and the
     * correct/incorrect responses on various dates
     */

    private static final String statsTable = "statsTable";

    // ----------------------------------------------------------------------------------

    /** String representing the piece field of the piece table */

    private static final String pieceField = "piece";

    /** String representing the type field of the piece table */

    private static final String typeField = "isPlay";

    /** String representing the point field of the specific table */

    private static final String pointField = "point";

    /** String representing the element field of the element table */

    private static final String elementField = "element";

    /** String representing the elType field of the element table */

    private static final String elTypeField = "isCharacter";

    /** String representing the quote field of the quote table */

    private static final String quoteField = "quote";

    /** String representing the ID field of the stats table */

    private static final String idField = "statId";

    /** String representing the correct field of the stats table */

    private static final String correctField = "correct";

    /** String representing the incorrect field of the stats table */

    private static final String incorrectField = "incorrect";

    /** String representing the date field of the stats table */

    private static final String dateField = "date";

    // ----------------------------------------------------------------------------------

    /** String array representing all the fields of the piece table */

    private static final String[] pieceTableFields = { pieceField, typeField };

    /** String array representing all the fields of the specific table */

    private static final String[] specificTableFields = { pointField,
            elementField };

    /** String array representing all the fields of the quote table */

    private static final String[] quoteTableFields = { quoteField, pointField };

    /** String array representing all the fields of the element table */

    private static final String[] elementTableFields = { elementField,
            pieceField, elTypeField };

    /** String array representing all the fields of the stats table */

    private static final String[] statsTableFields = { idField, pieceField,
            correctField, incorrectField, dateField };

    // ----------------------------------------------------------------------------------

    /** SQL statement to create the piece table. */

    private static final String createPieceTable = "CREATE TABLE " + pieceTable
            + " (" + pieceField + " TEXT NOT NULL PRIMARY KEY, " + typeField
            + " INTEGER);";

    /** SQL statement to create the specific table. */

    private static final String createSpecificTable = "CREATE TABLE "
            + specificTable + "(" + pointField + " TEXT NOT NULL PRIMARY KEY,"
            + elementField + " TEXT NOT NULL);";

    /** SQL statement to create the quotes table. */

    private static final String createQuoteTable = "CREATE TABLE " + quoteTable
            + " (" + quoteField + " TEXT NOT NULL, " + pointField
            + " TEXT NOT NULL, PRIMARY KEY (" + quoteField + ", " + pointField
            + "));";

    /** SQL statement to create the element table. */

    private static final String createElementTable = "CREATE TABLE "
            + elementTable + "(" + elementField + " TEXT NOT NULL PRIMARY KEY,"
            + pieceField + " TEXT NOT NULL," + elTypeField + " INTEGER);";

    /** SQL statement to create the stats table. */

    private static final String createStatsTable = "CREATE TABLE " + statsTable
            + "(" + idField + " INTEGER PRIMARY KEY AUTOINCREMENT,"
            + pieceField + " TEXT NOT NULL," + correctField + " INTEGER,"
            + incorrectField + " INTEGER," + dateField + " LONG);";

    // ----------------------------------------------------------------------------------

    /**
     * SQL statement to search the piece table - replace [columnName] and
     * [value] with field to be searched and what value to look for.
     */

    private static final String searchPieceTable = "SELECT * FROM "
            + pieceTable + " WHERE [columnName] = '[value]';";

    /**
     * SQL statement to search the specific table - replace [columnName] and
     * [value] with field to be searched and what value to look for.
     */

    private static final String searchSpecificTable = "SELECT * FROM "
            + specificTable + " WHERE [columnName] = '[value]';";

    /**
     * SQL statement to search the quote table - replace [columnName] and
     * [value] with field to be searched and what value to look for.
     */

    private static final String searchQuoteTable = "SELECT * FROM "
            + quoteTable + " WHERE [columnName] = '[value]';";

    /**
     * SQL statement to search the element table - replace [columnName] and
     * [value] with field to be searched and what value to look for.
     */

    private static final String searchElementTable = "SELECT * FROM "
            + elementTable
            + " WHERE [columnName] = '[value]' AND [columnName2] = '[value2]';";

    /**
     * SQL statement to search the stats table - replace [columnName] and
     * [value] with field to be searched and what value to look for.
     */

    private static final String searchStatsTable = "SELECT * FROM "
            + statsTable + " WHERE [columnName] = '[value]'";


    /**
     * SQL statement to delete from the piece table - replace [condition] the
     * condition where if true, this deletion should be applied.
     */

    private static final String deleteFromPieceTable = "DELETE FROM "
            + pieceTable + " WHERE [condition]";

    /**
     * SQL statement to delete from the specific table - replace [condition] the
     * condition where if true, this deletion should be applied.
     */

    private static final String deleteFromSpecificTable = "DELETE FROM "
            + specificTable + " WHERE [condition]";

    /**
     * SQL statement to delete from the quote table - replace [condition] the
     * condition where if true, this deletion should be applied.
     */

    private static final String deleteFromQuoteTable = "DELETE FROM "
            + quoteTable + " WHERE [condition]";

    /**
     * SQL statement to delete from the element table - replace [condition] the
     * condition where if true, this deletion should be applied.
     */

    private static final String deleteFromElementTable = "DELETE FROM "
            + elementTable + " WHERE [condition]";

    /**
     * SQL statement to delete from the stats table - replace [condition] the
     * condition where if true, this deletion should be applied.
     */

    private static final String deleteFromStatsTable = "DELETE FROM "
            + statsTable + " WHERE [condition]";

    // ----------------------------------------------------------------------------------

    /**
     * SQL statement to insert into the piece table - replace [values] with the
     * values to be inserted.
     */

    private static final String insertIntoPieceTable = "INSERT INTO "
            + pieceTable + " VALUES ([values]);";

    /**
     * SQL statement to insert into the specific table - replace [values] with
     * the values to be inserted.
     */

    private static final String insertIntoSpecificTable = "INSERT INTO "
            + specificTable + " VALUES ([values])";

    /**
     * SQL statement to insert into the quote table - replace [values] with the
     * values to be inserted.
     */

    private static final String insertIntoQuoteTable = "INSERT INTO "
            + quoteTable + " VALUES ([values])";

    /**
     * SQL statement to insert into the element table - replace [values] with
     * the values to be inserted.
     */

    private static final String insertIntoElementTable = "INSERT INTO "
            + elementTable + " VALUES ([values])";

    /**
     * SQL statement to insert into the quote table - replace [values] with the
     * values to be inserted.
     */

    private static final String insertIntoStatsTable = "INSERT INTO "
            + statsTable + " VALUES ([values])";

    // ----------------------------------------------------------------------------------

    /**
     * SQLiteDatabase representing the English database
     */

    private SQLiteDatabase dataBase;

    /**
     * Instance of DatabaseHelper class utilised to 'access' database
     */

    private DatabaseHelper baseHelper;

    /**
     * Content of the Database Manipulator (ManipulateDatabase class)
     */

    private Activity context;

    /**
     * Boolean to store whether or not this is the first time this base/version
     * has been launched
     */

    private boolean initialLaunch = false;

    /**
     * File for the BufferedReader to read into Database
     */

    private File pieceList;

    /**
     * Method to get pieceList file from assets for BufferedReader to use
     * 
     * @param ctx
     * @throws IOException
     */

    private InputStream getPieceTextFile(Activity ctx) throws IOException {

        try {
            AssetManager manager = ctx.getAssets();
            InputStream pieceStream = manager.open("pieceList.txt");
            return pieceStream;
        } catch (Exception e) {
            System.out.println("Asset Manager/IS not work.");
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Method to get specificList file from assets for BufferedReader to use
     * 
     * @param ctx
     * @throws IOException
     */

    private InputStream getSpecificTextFile(Activity ctx) throws IOException {

        try {
            AssetManager manager = ctx.getAssets();
            InputStream specificStream = manager.open("specificList.txt");
            return specificStream;
        } catch (Exception e) {
            System.out.println("Asset Manager/IS not work.");
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Method to get elementList file from assets for BufferedReader to use
     * 
     * @param ctx
     * @throws IOException
     */

    private InputStream getElementTextFile(Activity ctx) throws IOException {

        try {
            AssetManager manager = ctx.getAssets();
            InputStream elementStream = manager.open("elementList.txt");
            return elementStream;
        } catch (Exception e) {
            System.out.println("Asset Manager/IS not work.");
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Method to get quoteList file from assets for BufferedReader to use
     * 
     * @param ctx
     * @throws IOException
     */

    private InputStream getQuoteTextFile(Activity ctx) throws IOException {

        try {
            AssetManager manager = ctx.getAssets();
            InputStream quoteStream = manager.open("quoteList.txt");
            return quoteStream;
        } catch (Exception e) {
            System.out.println("Asset Manager/IS not work.");
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Method to open the database
     */

    private void openSesame() {
        try {
            dataBase = baseHelper.getWritableDatabase();
        } catch (SQLiteException e) {
            System.out.println("Database couldn't be opened");
            e.printStackTrace();
        }
    }

    /**
     * Method to close the database
     */

    private void closeSesame() {
        baseHelper.close();
    }

    /**
     * 
     * @param typePiece
     *            The type of the piece (a play or novel) to fetch from
     *            database, represented as 1 or 0 respectively.
     * 
     * @return pieces ArrayList containing the Strings to be returned (data
     *         items that fulfill the criteria)
     */
    public ArrayList<String> getPieces(String typePiece) {
        try {
            openSesame();

            ArrayList<String> pieces = new ArrayList<String>();
            String command = searchPieceTable
                    .replace("[columnName]", typeField);
            command = command.replace("[value]", typePiece);

            Cursor cursor = dataBase.rawQuery(command, null);
            cursor.moveToFirst();
            while (!cursor.isAfterLast()) {
                pieces.add(cursor.getString(cursor.getColumnIndex(pieceField)));
                System.out
                        .println(cursor.getString(cursor
                                .getColumnIndex(pieceField))
                                + " HAS JUST BEEN ADDED TO PIECE ARRAYLIST FETCHED FROM DB");
                cursor.moveToNext();
            }
            closeSesame();
            return pieces;
        } catch (SQLiteException e) {
            e.printStackTrace();
            System.out.println("SQL Problem");
            ArrayList<String> defaultReturn = new ArrayList<String>();
            defaultReturn.add("There is default item.");
            defaultReturn.add("Because the proper ArrayList");
            defaultReturn.add("Wasn't filled properly");
            return defaultReturn;
        }
    }

    /**
     * 
     * @param namePiece
     *            String representing the piece which the elements wanted are
     *            from
     * @param typeElement
     *            String representing the type of element to extract
     *            (character/theme)
     * 
     * @param appendage
     *            String representing the additional criteria that might want to
     *            be added to the SQL SELECT statement
     * 
     * @return elements ArrayList containing the Strings of the elements
     * 
     */

    public ArrayList<String> getElements(String namePiece, String typeElement,
            String appendage) {
        try {
            openSesame();
            ArrayList<String> elements = new ArrayList<String>();
            String command = searchElementTable.replace("[columnName]",
                    pieceField);
            command = command.replace("[value]", namePiece);
            command = command.replace("[columnName2]", elTypeField);
            command = command.replace("[value2]", typeElement);

            Cursor cursor = dataBase.rawQuery(command, null);
            cursor.moveToFirst();
            while (!cursor.isAfterLast()) {
                elements.add(cursor.getString(cursor
                        .getColumnIndex(elementField)));
                System.out
                        .println(cursor.getString(cursor
                                .getColumnIndex(elementField))
                                + " HAS JUST BEEN ADDED TO ELEMENT ARRAYLIST FETCHED FROM DB");
                cursor.moveToNext();
            }
            closeSesame();
            return elements;

        } catch (SQLiteException e) {
            e.printStackTrace();
            System.out.println("SQL Problem");
            ArrayList<String> defaultReturn = new ArrayList<String>();
            defaultReturn.add("There is default item.");
            defaultReturn.add("Because the proper ArrayList");
            defaultReturn.add("Wasn't filled properly");
            return defaultReturn;
        }
    }

    /**
     * 
     * @param nameElement
     *            String representing the element to which the points belong
     * 
     * 
     * @param appendage
     *            String representing the additional criteria that might want to
     *            be added to the SQL SELECT statement
     * 
     * @return points ArrayList containing the Strings of the points
     * 
     */

    public ArrayList<String> getPoints(String nameElement, String appendage) {
        try {
            openSesame();
            ArrayList<String> points = new ArrayList<String>();
            String command = searchSpecificTable.replace("[columnName]",
                    elementField);
            command = command.replace("[value]", nameElement);
            command = command.concat(appendage);

            Cursor cursor = dataBase.rawQuery(command, null);
            cursor.moveToFirst();
            while (!cursor.isAfterLast()) {
                points.add(cursor.getString(cursor.getColumnIndex(pointField)));
                System.out
                        .println(cursor.getString(cursor
                                .getColumnIndex(pointField))
                                + " HAS JUST BEEN ADDED TO ELEMENT ARRAYLIST FETCHED FROM DB");
                cursor.moveToNext();
            }
            closeSesame();
            return points;

        } catch (SQLiteException e) {
            e.printStackTrace();
            System.out.println("SQL Problem");
            ArrayList<String> defaultReturn = new ArrayList<String>();
            defaultReturn.add("There is default item.");
            defaultReturn.add("Because the proper ArrayList");
            defaultReturn.add("Wasn't filled properly");
            return defaultReturn;
        }
    }

    /**
     * 
     * @param namePoint
     *            String representing the point to which the quote belongs
     * 
     * 
     * 
     * @return points ArrayList containing the Strings of the points
     * 
     */

    public ArrayList<String> getQuotes(String namePoint) {
        try {
            openSesame();
            ArrayList<String> quotes = new ArrayList<String>();
            String command = searchQuoteTable.replace("[columnName]",
                    pointField);
            command = command.replace("[value]", namePoint);

            Cursor cursor = dataBase.rawQuery(command, null);
            cursor.moveToFirst();
            while (!cursor.isAfterLast()) {
                String adjustedQuote = '"' + cursor.getString(cursor
                        .getColumnIndex(quoteField)) + '"';
                String unadjustedQuote = cursor.getString(cursor
                        .getColumnIndex(quoteField));
                Tester test = new Tester();
                if (test.isNeedQuoteMarks()) {
                    quotes.add(adjustedQuote);
                } else {
                    quotes.add(unadjustedQuote);
                }

                System.out
                        .println(cursor.getString(cursor
                                .getColumnIndex(quoteField))
                                + " HAS JUST BEEN ADDED TO ELEMENT ARRAYLIST FETCHED FROM DB");
                cursor.moveToNext();
            }
            closeSesame();
            return quotes;

        } catch (SQLiteException e) {
            e.printStackTrace();
            System.out.println("SQL Problem");
            ArrayList<String> defaultReturn = new ArrayList<String>();
            defaultReturn.add("There is default item.");
            defaultReturn.add("Because the proper ArrayList");
            defaultReturn.add("Wasn't filled properly");
            return defaultReturn;
        }
    }

    public int getLatestCorrect(String namePiece) {

        try {
            openSesame();
            String command = "SELECT MAX(correct) FROM statsTable WHERE piece = '"
                    + namePiece + "';";

            Cursor cursor = dataBase.rawQuery(command, null);
            cursor.moveToFirst();
            int value = (cursor.getInt(cursor.getColumnIndex(correctField)));
            closeSesame();
            return value;
        } catch (Exception e) {
            System.out.println("Caught excption from getLastCorrect");
            return 0;
        }
    }

    public int getLatestIncorrect(String namePiece) {

        try {
            openSesame();
            String command = "SELECT MAX(incorrect) FROM statsTable WHERE piece = '"
                    + namePiece + "';";

            Cursor cursor = dataBase.rawQuery(command, null);
            cursor.moveToFirst();
            int value = (cursor.getInt(cursor.getColumnIndex(incorrectField)));
            closeSesame();
            return value;
        } catch (Exception e) {
            System.out.println("Caught exception from getLastIncorrect");
            return 0;
        }
    }

    public void addPiece(String namePiece, String isDrama) {
        openSesame();
        ContentValues adPi = new ContentValues();
        adPi.put(pieceField, namePiece);
        System.out.println(pieceField + ": " + namePiece);
        adPi.put(typeField, (Integer.parseInt(isDrama)));
        System.out.println(typeField + ": " + (isDrama));
        dataBase.insert(pieceTable, null, adPi);
        System.out.println("INSERTED " + namePiece + " IS D: " + isDrama);
        closeSesame();

    }

    public void deletePiece(String namePiece) {
        openSesame();
        String command = deleteFromPieceTable.replace("[condition]", pieceField
                + "= '" + namePiece + "';");
        dataBase.execSQL(command);
        closeSesame();

    }

    public void addElement(String nameElement, String namePiece, String isChar) {
        openSesame();
        ContentValues adEl = new ContentValues();
        adEl.put(elementField, nameElement);
        adEl.put(pieceField, namePiece);
        adEl.put(elTypeField, (Integer.parseInt(isChar)));
        dataBase.insert(elementTable, null, adEl);
        System.out.println("INSERTED " + nameElement + "FROM " + namePiece
                + " IS C: " + isChar);
        closeSesame();
    }

    public void deleteElement(String nameElement) {
        openSesame();
        String command = deleteFromElementTable.replace("[condition]",
                elementField + "= '" + nameElement + "';");
        dataBase.execSQL(command);
        closeSesame();

    }

    public void addPoint(String namePoint, String nameElement) {
        openSesame();
        ContentValues adPo = new ContentValues();
        adPo.put(pointField, namePoint);
        adPo.put(elementField, nameElement);
        dataBase.insert(specificTable, null, adPo);
        System.out.println("INSERTED " + namePoint + "FOR " + nameElement);
        closeSesame();
    }

    public void deletePoint(String namePoint) {
        openSesame();
        String command = deleteFromSpecificTable.replace("[condition]",
                pointField + "= '" + namePoint + "';");
        dataBase.execSQL(command);
        closeSesame();
    }

    public void addQuote(String nameQuote, String namePoint) {
        System.out.println("INSIDE INSERT QUOTE");
        openSesame();
        ContentValues adQu = new ContentValues();
        adQu.put(quoteField, nameQuote);
        adQu.put(pointField, namePoint);
        dataBase.insert(quoteTable, null, adQu);
        System.out.println("INSERTED " + nameQuote + " FOR " + namePoint);
        closeSesame();
    }

    public void deleteQuote(String nameQuote) {
        openSesame();
        String command = deleteFromQuoteTable.replace("[condition]", quoteField
                + "= '" + nameQuote + "';");
        dataBase.execSQL(command);
        closeSesame();
    }

    public void addStat(String pieceName, int correct, int incorrect, long date) {
        openSesame();
        ContentValues adSt = new ContentValues();
        adSt.put(pieceField, pieceName);
        adSt.put(correctField, correct);
        adSt.put(incorrectField, incorrect);
        adSt.put(dateField, date);
        dataBase.insert(statsTable, null, adSt);
        System.out.println("INSERTED " + correct + " correct and " + incorrect
                + " incorrect FOR " + pieceName);
        closeSesame();

    }

1 个答案:

答案 0 :(得分:2)

您的光标有一行“MAX(不正确)”,您试图选择“不正确”列

您需要为列添加“MAX(不正确)”等别名,然后它才能正常工作。