以下是我从数据库中读取的代码:
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
const char *query_stmt = "SELECT QuestionID, question, RightAnswer,WrongAnswer1, WrongAnswer2, audio FROM questions WHERE done='no' AND Catagory='%@'", Catagory;
int check = (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL));
NSLog(@"%i",check);
if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
while(sqlite3_step(statement) == SQLITE_ROW)
{
questionID = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
questionString = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
rightAnswerString = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
wrong1AnswerString = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)];
wrong2AnswerString = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 4)];
audioInteger = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 5)];
break;
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
}
我想在我的表的第一行中读取done='no'
,并且类别与存储在变量catagory中的类别相匹配。我以为我可以使用while语句然后在循环之前断开。但是,永远不会满足while语句的条件。这告诉我,sql语句没有返回任何值。
数据库的SQL如下:
DROP TABLE IF EXISTS "Questions";
CREATE TABLE "Questions" ("QuestionID" INTEGER PRIMARY KEY NOT NULL , "Question" TEXT, "RightAnswer" TEXT, "WrongAnswer1" TEXT, "WrongAnswer2" TEXT, "Done" BOOL, "Catagory" TEXT, "Audio" INTEGER);
INSERT INTO "Questions" VALUES(1,'What is the BPM of this piece?','120 BPM','70 BPM','170 BPM','no','Rhythm',1);
INSERT INTO "Questions" VALUES(2,'How far apart are the 2 notes the bass guitar plays?','4 Semitones','1 Semitone','6 Tones','no','Pitch',1);
INSERT INTO "Questions" VALUES(3,'How is the organ Panned?','Left','Right','Centre','no','Pan',1);
INSERT INTO "Questions" VALUES(4,'What are the note values of the HiHat rhythms?','Semi quaver','Quaver','Crotchet','no','Rhythm',1);
INSERT INTO "Questions" VALUES(5,'The first chord played on the organ is...','Minor','Major','Atonal','no','Pitch',1);
INSERT INTO "Questions" VALUES(6,'How is the bass sound panned in this piece?','Right','Left','Center','no','Pan',2);
INSERT INTO "Questions" VALUES(7,'How is the lead synth panned in this piece?','Left','Right','Center','no','Pan',2);
INSERT INTO "Questions" VALUES(8,'The Kick Drum Rhythm In this can abe described as...','Four to the Floor','Off beat','Minor','no','Rhythm',2);
INSERT INTO "Questions" VALUES(9,'A clap sound can be heard on beat..','2 and 4','1 and 3','3','no','Rhythm',2);
DROP TABLE IF EXISTS "Results";
CREATE TABLE "Results" ("ResultID" INTEGER PRIMARY KEY NOT NULL , "QuestionRight" INTEGER, "TotalQuestions" INTEGER, "Catagory" TEXT);
所以我要问的是:
1)有没有更好的方法只读取满足我的sql语句的第一行?
2)我目前的方法是否有效?
感谢您的帮助,
本
*************更新*************
这是定义类别的地方:
CatagoryLoaded = [[NSUserDefaults standardUserDefaults] integerForKey:@"catagorysaved"];
switch (CatagoryLoaded) {
case 1:
CatagorySelected.text = [NSString stringWithFormat:@"Pan!"];
Catagory = @"pan";
break;
case 2:
CatagorySelected.text = [NSString stringWithFormat:@"Pitch!"];
Catagory = @"pitch";
break;
case 3:
CatagorySelected.text = [NSString stringWithFormat:@"Rhythm!"];
Catagory = @"rhythm";
break;
default:
break;
}
*************更新2 *************
我按照您的建议将其更改为限制1,现在正在获取thread1: signal SIGABRT
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
const char *query_stmt = "SELECT * FROM Questions WHERE Done='no' AND Catagory='%@' LIMIT 1", Catagory;
int check = (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL));
NSLog(@"%i",check);
if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
questionID = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
questionString = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
rightAnswerString = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
wrong1AnswerString = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)];
wrong2AnswerString = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 4)];
audioInteger = [[NSString alloc]initWithUTF8String:(const char *) sqlite3_column_text(statement, 5)];
sqlite3_finalize(statement);
}
sqlite3_close(database);
}
*************更新*************
看起来声明将其保留为'%@'
而不是存储在类别中的任何内容,任何想法为什么?
下面是一个屏幕截图的链接,显示SIGABRT崩溃前的变量。 (不会让我直接发布图片,因为我是网站新手)
答案 0 :(得分:1)
我唯一的猜测是你的“类别”变量不是有效的。除此之外,SQL语句看起来不错。我不记得SQLite是否区分大小写,但将Done和Questions以及其他内容放在适当的情况下并没有什么坏处。
此外,出于性能原因,您始终可以在SQL语句末尾添加“限制1”以获取第一行。或者只是将其从WHILE更改为IF,因此它只运行一次,但是,我建议使用LIMIT语法。
NSString *query_stmt = [NSString stringWithFormat:"SELECT * FROM Questions WHERE Done='no' AND Catagory='%@' LIMIT 1", Catagory];