【问题标题】:Reading from a Database in an iPhone app从 iPhone 应用程序中的数据库读取
【发布时间】:2015-06-27 14:15:30
【问题描述】:

下面是我从数据库中读取的代码:

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) 我当前的方法不起作用是有原因的吗?

感谢您的帮助,

****************** 更新 *************

这里是定义类别的地方:

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 崩溃前显示变量的屏幕截图链接。 (不会让我直接发布图片,因为我是该网站的新手)

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

【问题讨论】:

  • 您永远不会绑定类别的值。
  • 这是什么意思? (我是IOS开发新手)。
  • , Catagory 不会像您认为的那样做。您需要使用NSString stringWithFormat
  • 感谢您的建议,但您能否写出完整的代码行,因为我不太明白。谢谢
  • 使用了NSString *query_string = [NSString stringWithFormat:@"SELECT QuestionID, Question, RightAnswer,WrongAnswer1, WrongAnswer2, Audio FROM Questions WHERE Done='no' AND Catagory='%@'", Catagory]; const char *query_stmt = [query_string UTF8String];,感谢您的建议:)

标签: ios objective-c database xcode sqlite


【解决方案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];

【讨论】:

  • 已将代码添加到我定义“类别”的问题中
  • 我认为 SQLite 中的列名不区分大小写,但值是。您的类别值需要与数据库中值的大小写相匹配。例如:“节奏”而不是“节奏”......这太疯狂了......
  • 您的答案最初被否决,因为它没有回答问题并且发布的代码是错误的。代码现已修复(尽管它可能有助于向 OP 展示如何从 NSString 获取 char *)。
  • 我可以理解代码是否错误(不熟悉“const char *”语法),但我不相信我没有试图帮助回答他的问题。当任何帮助人们的尝试都被否决时,这是非常令人沮丧的,这似乎经常发生。
猜你喜欢
  • 2015-06-25
  • 1970-01-01
  • 1970-01-01
  • 2011-07-06
  • 2013-04-24
  • 2015-11-26
  • 1970-01-01
  • 2020-06-02
  • 2011-09-17
相关资源
最近更新 更多