2015-04-20 3 views
0

Ниже мой код для чтения из базы данных:Чтения из базы данных в iPhone приложении

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' и категория соответствуют категориям, хранящимся в переменная категория. Я думал, что смогу сделать это, используя инструкцию 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) есть ли причина, по которой мой текущий метод не работает?

Спасибо за вашу помощь,

Бен

************* ************* UPDATE

Здесь находится где категория определяется:

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

************* UPDATE 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); 
} 

************* ************* UPDATE выглядит заявление покидает его как '%@' вместо что когда-либо хранится в категории, любая идея, почему?

Ниже приведена ссылка на экран, показывающий переменные непосредственно перед сбоем SIGABRT. (Не позволит мне разместить изображение непосредственно, как я впервые на сайте)

http://puu.sh/hkOxf/8c05b9489b.png

+0

Вы никогда не привязываетесь к значению для категории. – rmaddy

+0

Что вы подразумеваете под этим? (Я новичок в разработке IOS). –

+0

', Catagory' не делает то, что вы думаете. Вам нужно использовать 'NSString stringWithFormat'. – rmaddy

ответ

1

Мое единственное предположение, что ваша «Категория» переменная не является допустимым. Кроме этого, выражение SQL выглядит хорошо. Я не помню, если SQLite чувствителен к регистру, но не помешает положить Done и Questions и все в правильном случае.

Кроме того, по соображениям производительности вы всегда можете добавить «Предел 1» в конец вашего оператора SQL, чтобы получить первую строку. Или просто измените его с WHILE на IF вместо этого, поэтому он запускается только один раз, однако я рекомендую использовать синтаксис LIMIT.

NSString *query_stmt = [NSString stringWithFormat:"SELECT * FROM Questions WHERE Done='no' AND Catagory='%@' LIMIT 1", Catagory]; 
+0

Добавили код к моему вопросу, где я определяю 'catagory' –

+0

Я не думаю, что имена столбцов в SQLite чувствительны к регистру, но значения. Значения вашей категории должны соответствовать случаю значений в вашей БД. Например: «Ритм» не «ритм» .... это безумие, чтобы спуститься, проголосовали за это ... –

+1

Не проголосовали за меня. Я нашел ваш совет полезным. –

Смежные вопросы