Android 如何限制sqlite查询中ID的随机数?

Android 如何限制sqlite查询中ID的随机数?,android,sql,database,sqlite,android-sqlite,Android,Sql,Database,Sqlite,Android Sqlite,我正在应用程序中使用SQLite数据库。应用程序应该以随机顺序选择一组指定的问题ID。我还想把问题限制在我指定的21个ID内。然而,每当我运行应用程序时,我都能够回答第22个问题。我有两个问题 我认为我的sql查询没有选择语句中指定的正确问题ID 回答第21个问题后,应用程序应停止,并且不允许查看任何进一步的测试材料。这也不会发生 我对android库项目和SQLite比较陌生,希望您能给予帮助 请参见下面的我的GTestBankDB类文件: public class TestBankDB {

我正在应用程序中使用SQLite数据库。应用程序应该以随机顺序选择一组指定的问题ID。我还想把问题限制在我指定的21个ID内。然而,每当我运行应用程序时,我都能够回答第22个问题。我有两个问题

  • 我认为我的sql查询没有选择语句中指定的正确问题ID

  • 回答第21个问题后,应用程序应停止,并且不允许查看任何进一步的测试材料。这也不会发生

  • 我对android库项目和SQLite比较陌生,希望您能给予帮助

    请参见下面的我的GTestBankDB类文件:

    public class TestBankDB {
    private static final String DEFAULT_DB_NAME = "test.db";
    private static final String TEMP_DB_NAME = "temp.db";
    
    private SQLiteDatabase db;
    private static SQLiteDatabase testDatabase;
    
    public enum TestType {
        SEEN_LEAST,
        MISSED_MOST
    }
    
    public TestBankDB(SQLiteDatabase db) {
        this.db = db;
    }
    
    public void close() {
        db.close();
        db = null;
    }
    
    
    public int getDataVersion() {
        return getInt("select max(id) from version");
    }
    
    public String getEquationName(int id) {
        return getString("select file_name from equations where id = " +     id).toLowerCase();
    }
    
    public void setGlobalStats(int questionId, int seenCount, int correctCount) {
        String sql = String.format("update questions set global_count = %d,                              global_correct = %d where id = %d", seenCount, correctCount, questionId); 
        db.execSQL(sql);
    }
    
    public List<Integer> getQuestionsForSubjects(int[] subjectIds, TestType type, boolean favoritesOnly) {
    
        // Gather individual questions
        String sql = "select id from questions where subject in (" + join(subjectIds) + ") and (case_id is null or case_id == 0) " + (favoritesOnly ? "and favorite > 0" : "");
    
        //String sql = "SELECT id from questions WHERE ID IN (84, 8791, 8349)";
    
        // pulls only questions with tables in them, note encryption in LIKE condition
        // String sql = "select id from questions where qtext LIKE '%<Q98Y5%' and subject in (" + join(subjectIds) + ") and (case_id is null or case_id == 0) " + (favoritesOnly ? "and favorite > 0" : "");
    
        switch (type) {
            case SEEN_LEAST: sql += " ORDER BY SEEN_COUNT, RANDOM()"; break;
            case MISSED_MOST: sql += " ORDER BY INCORRECT_COUNT DESC, SEEN_COUNT, RANDOM()"; break;
        }
        //Cursor cursor = db.rawQuery(sql, new String[]{});
        Cursor cursor = query(sql);
    
        List<Integer> list = new ArrayList<Integer>();
        while (cursor.moveToNext()) {
            list.add(cursor.getInt(0));
        }
        LogIt.d(this, "Loaded question count = " + list.size());
        cursor.close();
    
        // Gather case questions
        sql = "select id, case_id from questions where subject in (" + join(subjectIds) + ") and case_id > 0 " + (favoritesOnly ? "and favorite > 0" : "") + " order by case_id, id";
        List<Integer> questionIdList = null;
        List<CaseGroup> caseList = new ArrayList<CaseGroup>();
        //cursor = db.rawQuery(sql, new String[]{});
        cursor = query(sql);
        int currentCase = -1;
        while (cursor.moveToNext()) {
    
            int questionId = cursor.getInt(0);
            int caseId = cursor.getInt(1);
    
            if (currentCase < 0 || currentCase != caseId) {
                 questionIdList = new ArrayList<Integer>();
                 caseList.add(new CaseGroup((int)(MiscUtil.random()*list.size()), questionIdList));
    
    公共类TestBankDB{
    私有静态最终字符串DEFAULT\u DB\u NAME=“test.DB”;
    私有静态最终字符串TEMP\u DB\u NAME=“TEMP.DB”;
    专用数据库数据库;
    私有静态SQLiteDatabase testDatabase;
    公共枚举测试类型{
    至少,
    最想念你
    }
    公共TestBankDB(sqlitedatabasedb){
    这个.db=db;
    }
    公众假期结束(){
    db.close();
    db=null;
    }
    public int getDataVersion(){
    返回getInt(“从版本中选择最大值(id”);
    }
    公共字符串GetEqualationName(int id){
    返回getString(“从公式中选择文件名,其中id=“+id”).toLowerCase();
    }
    public void setGlobalStats(int questionId、int seenCount、int correctCount){
    String sql=String.format(“更新问题集全局\u计数=%d,全局\u更正=%d,其中id=%d”,请参阅计数,更正计数,问题id);
    execSQL(sql);
    }
    public List getQuestionsForSubjects(int[]SubjectId,TestType类型,仅布尔型偏好){
    //收集个人问题
    String sql=“从问题中选择id,其中主题位于(“+join(subjectId)+”)和(case_id为null或case_id==0)”+(favoritesOnly?”和favorite>0:”;
    //String sql=“从id位于(8487918349)中的问题中选择id”;
    //只提取包含表格的问题,注意类似条件下的加密
    
    //String sql=“从问题中选择id,其中qtext类似“%I”我不确定该问题是否在您的sql查询中,但我更感兴趣的是您如何处理显示下一个问题。假设您总是调用
    getQuestion()
    要想得到下一个问题,那么应该检查它是否已经被调用了21次。我还担心,使用当前方法,您可能会遇到重复的问题。您知道我将如何设置检查以查看它是否被调用了21次吗?我正在研究如何限制行数,并防止查询返回相同的ID两次,对吗“我没有发现太多…任何想法都会很酷!我是这个项目的新手,代码是由以前的开发人员编写的。我现在不确定他是如何处理问题调用的。我今晚正在调查我有这个想法,但变化可能很大,因为它取决于问题调用代码。稍后,在您修改问题调用代码后。”我会再检查一遍。已经为数据库构建的代码通常不会在回答问题时复制问题。我正在尝试找出为什么当我将问题集限制为21个随机选择的问题时,它似乎忽略了限制,然后开始抛出重复的问题。我没有更改getQue的SQL输入特定ID和添加RANDOM()order by子句以外的查询。以下是完整数据库活动的代码,用于处理将问题材料传递到应用程序UI的过程。请参阅我的问题编辑
            questionIdList.add(questionId);
        }
        cursor.close();
    
        Collections.sort(caseList);
        while (caseList.size() > 0) {
            CaseGroup group = caseList.remove(0);
            list.addAll(group.idx, group.questionIds);
            for (int i = 0; i < caseList.size(); i++) {
                caseList.get(i).idx += group.questionIds.size();
            }
        }
    
        return list;
    }
    
    public String getCaseText(int id) {
        return Allen.decrypt(getString("select text from cases where id = " + id));
    }
    
    public Subject getSubject(int id) {
        String name = getString("select subject from subjects where id = " + id);
    
        String sql = id == 0 ? 
                "SELECT count(*), sum(SEEN_COUNT), sum(INCORRECT_COUNT), sum(FAVORITE) FROM questions" :
                "SELECT count(*), sum(SEEN_COUNT), sum(INCORRECT_COUNT), sum(FAVORITE) FROM questions WHERE SUBJECT = " + id;
    
        Cursor cursor = db.rawQuery(sql, new String[]{});
        cursor.moveToFirst();
    
        int questionCount = cursor.getInt(0);
        int seenCount = cursor.getInt(1);
        int incorrectCount = cursor.getInt(2);
        int favoriteCount = cursor.getInt(3);
        cursor.close();
    
        Subject subject = new Subject(id, name, questionCount, seenCount, incorrectCount, favoriteCount); 
    
        return subject;
    }
    
    public List<Integer> getAllSubjects() {
    
        String sql = "select id from subjects";
        //Cursor cursor = db.rawQuery(sql, new String[enter code here]{});
        Cursor cursor = query(sql);
    
        List<Integer> list = new ArrayList<Integer>();
        while (cursor.moveToNext()) {
            list.add(cursor.getInt(0));
        }
    
        cursor.close();
    
        return list;
    }
    
    private String join(int[] items) {
        StringBuilder builder = new StringBuilder();
    
        for (int i = 0; i < items.length; i++) {
            builder.append(items[i]);
            if (i < items.length-1) {
                builder.append(",");
            }
        }
    
        return builder.toString();
    }
    
    public void resetPerformanceStatistics() {
        db.execSQL("update questions set seen_count = 0, incorrect_count = 0");
    }
    
    public void resetFavoriteQuestions() {
        db.execSQL("update questions set favorite = false");
    }
    
    public void resetNeverShowQuestions() {
        db.execSQL("update questions set never_see = false");
    }
    
    public void failQuestion(int id) {
        db.execSQL(String.format("update questions set incorrect_count = (SELECT incorrect_count FROM questions where id = %d)+1 where id = %d", id, id));
    }
    
    public void favoriteQuestion(int id, boolean favorite) {
        db.execSQL(String.format("update questions set favorite = %d where id = %d", favorite ? 1 : 0, id));
    }
    
    public void neverShowQuestion(int id, boolean neverShow) {
        db.execSQL(String.format("update questions set never_see = %d where id = %d", neverShow ? 1 : 0, id));
    }
    
    public Question getQuestion(int id) {
        // Get question
        //String sql = "select id, subject, qtext, answer_1, answer_2, answer_3, answer_4, answer_5, answer_6, answer_7, answer_8, rationale, favorite, case_id, global_count, global_correct from questions where id = " + id;
        //sql = "select id, subject, qtext, answer_1, answer_2, answer_3, answer_4, answer_5, answer_6, answer_7, answer_8, rationale, favorite, case_id, global_count, global_correct from questions where id = 2180";
    
        // Some test questions with htmlSymbols in them
        String sql = "SELECT id, subject, qtext, answer_1, answer_2, answer_3, answer_4, answer_5, answer_6, answer_7, answer_8, rationale, favorite, case_id, global_count, global_correct FROM questions WHERE ID IN (58, 127, 216, 291, 809, 1638, 1954, 1966, 2115, 2442, 3253, 3538, 3650, 4033, 4062, 5150, 7946, 7967, 2663, 3704, 5248) ORDER BY RANDOM()";
    
        //LogIt.d(TestBankDB.class, "getQuestion() id = " + id);
        //LogIt.d(TestBankDB.class, "sql = " + id);
    
        Cursor cursor = query(sql);
        cursor.moveToFirst();
        Question q = Question.from(cursor);
        cursor.close();
        return q;
    }
    
    public void questionAnswered(int id) {
        db.execSQL(String.format("update questions set seen_count = (SELECT seen_count FROM questions where id = %d)+1 where id = %d", id, id));
    }
    
    public int getInt(String sql) {
    
        //Cursor cursor = db.rawQuery(sql, new String[]{});
        Cursor cursor = query(sql);
        cursor.moveToFirst();
        int value = cursor.getInt(0);
        cursor.close();
    
        return value; 
    }
    public String getString(String sql) {
    
        Cursor cursor = db.rawQuery(sql, new String[]{});
        cursor.moveToFirst();
        String value = cursor.getString(0);
        cursor.close();
    
        return value; 
    }
    
    private class CaseGroup implements Comparable<CaseGroup> {
        int idx;
        List<Integer> questionIds;
        public CaseGroup(int idx, List<Integer> questionIds) {
            this.idx = idx;
            this.questionIds = questionIds;
        }
        @Override
        public int compareTo(CaseGroup o) {
            return idx < o.idx ? -1 : idx == o.idx ? 0 : 1;
        }
    }
    
    public Cursor managedQuery(Activity activity, String sql) {
        Cursor c = query(sql);
        activity.startManagingCursor(c);
        return c;
    }
    
    public Cursor query(String sql) {
        return db.rawQuery(sql, null);
    }
    
    public boolean isClosed() {
        return !db.isOpen();
    }
    
    public static TestBankDB getDefault(Context context) {
        //return new TestBankDB(context.openOrCreateDatabase(DEFAULT_DB_NAME, SQLiteDatabase.CREATE_IF_NECESSARY, null));
        if (testDatabase == null || !testDatabase.isOpen()) {
            LogIt.d(TestBankDB.class, "CREATING DEFAULT DATABASE");
            testDatabase = context.openOrCreateDatabase(DEFAULT_DB_NAME, SQLiteDatabase.CREATE_IF_NECESSARY, null);
        }
        return new TestBankDB(testDatabase);
    }