Android 如何限制sqlite查询中ID的随机数?
我正在应用程序中使用SQLite数据库。应用程序应该以随机顺序选择一组指定的问题ID。我还想把问题限制在我指定的21个ID内。然而,每当我运行应用程序时,我都能够回答第22个问题。我有两个问题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 {
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);
}