从另一个视图控制器检索sqlite数据

时间:2012-08-27 11:02:32

标签: ios sqlite

我有一个名为VegQuantity的视图控制器,它执行totalcost =(数量*盘子的成本)并将itemname,quantity,totalcost插入名为FINALORDER的表中,数据库名称为FinalOrder

sqlite3_stmt    *statement;

const char *dbpath = [databasePath UTF8String];

if (sqlite3_open(dbpath, &FinalOrder) == SQLITE_OK)
{
    NSString *insertSQL = [NSString stringWithFormat: @"INSERT INTO FINALORDER (itemname, quantity, totalcost) VALUES (\"%@\", \"%@\", \"%@\")", itemName.text, input.text, output.text];

    const char *insert_stmt = [insertSQL UTF8String];

    sqlite3_prepare_v2(FinalOrder, insert_stmt, -1, &statement, NULL);
    if (sqlite3_step(statement) == SQLITE_DONE)
    {
        //  status.text = @"Contact added";
        //  name.text = @"";
        //  address.text = @"";
        //  phone.text = @"";
        NSLog(@"added");
    } else {
        NSLog(@"Couldnt add");
    }
    sqlite3_finalize(statement);
    sqlite3_close(FinalOrder);
}

Final View Controller viewdidload方法

const char *dbpath = [databasePath UTF8String];
sqlite3_stmt    *statement;

if (sqlite3_open(dbpath, &FinalOrder) == SQLITE_OK)
{
    NSString *querySQL = [NSString stringWithFormat: @"SELECT * FROM FINALORDER"];

    const char *query_stmt = [querySQL UTF8String];

    if (sqlite3_prepare_v2(FinalOrder, query_stmt, -1, &statement, NULL) == SQLITE_OK)
    {
        if (sqlite3_step(statement) == SQLITE_ROW)
        {
            NSString *itemname = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
            item.text = itemname;

            NSString *qua = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
            quantity.text = qua;

            NSString *total = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
            totalcost.text=total;
        }
        sqlite3_finalize(statement);
    }
    sqlite3_close(FinalOrder);
}

但是我在FinalOrder之前一直得到这个名为expected expression的错误,我在viewdidload中编写这段代码是否正确?我在最终视图控制器中没有任何按钮我在一个名为Restaurant的视图控制器中有一个名为order的按钮,它实际上显示了我最终视图控制器..我应该在Final viewcontroller中再次搜索db文件,我很抱歉问题看起来有点模糊,但简而言之,我只是想知道如何检索和显示我在VegQuantity视图控制器中插入到最终视图控制器中的数据,谢谢

1 个答案:

答案 0 :(得分:0)

我认为问题必须放在FinalOrder的定义中,在{1}}的定义中,基于错误消息,看起来已被定义为类,而不是sqlite3 *变量。鉴于您使用数据库的范围仅限于这两种方法,我建议在该范围内定义sqlite3 *,并使用它,例如:

- (void)saveRecord
{
    sqlite3      *database;
    sqlite3_stmt *statement;
    const char   *dbpath = [databasePath UTF8String];

    if (sqlite3_open(dbpath, &database) == SQLITE_OK)
    {
        [self purgeTable:database];

        NSString *insertSQL = @"INSERT INTO FINALORDER (itemname, quantity, totalcost) VALUES (?, ?, ?)";

        if (sqlite3_prepare_v2(database, [insertSQL UTF8String], -1, &statement, NULL) == SQLITE_OK)
        {
            sqlite3_bind_text(statement, 1, [itemName.text UTF8String], -1, NULL);
            sqlite3_bind_int(statement, 2, [input.text intValue]);
            sqlite3_bind_double(statement, 3, [output.text doubleValue]);

            if (sqlite3_step(statement) == SQLITE_DONE)
            {
                //  status.text = @"Contact added";
                //  name.text = @"";
                //  address.text = @"";
                //  phone.text = @"";
                NSLog(@"added");
            } else {
                NSLog(@"%s Couldn't add; errmsg='%s'", __FUNCTION__, sqlite3_errmsg(database));
            }
            sqlite3_finalize(statement);
        } else {
            NSLog(@"%s Couldn't prepare; errmsg='%s'", __FUNCTION__, sqlite3_errmsg(database));
        }

        sqlite3_close(database);
    }
}

注意,除了为数据库使用sqlite3 *变量之外,还要使其更加健壮:

  1. 我已使用stringWithFormat语句替换了构建SQL insert语句的INSERT语句,该语句使用?占位符,然后使用sqlite3_bind_text绑定值那个声明。这样,如果有人输入了包含引号的值,则insert语句仍然有效(原始实现会崩溃和/或容易受到SQL注入攻击)。

  2. 我还添加了sqlite3_errmsg语句,如果出现问题,我知道问题所在。

  3. 我不是将这三个字段视为文本字段,而是假设您的表定义为CREATE TABLE IF NOT EXISTS FINALORDER (itemname TEXT, quantity INT, totalcost REAL);,因此使用text,int和double绑定语句。

  4. 顺便提一下,这会调用purgeTable方法,所以如果你运行两次,它会删除那里的旧记录:

    - (void)purgeTable:(sqlite3 *)database
    {
        if (sqlite3_exec(database, "DELETE FROM FINALORDER;", NULL, NULL, NULL) != SQLITE_OK)
            NSLog(@"%s Couldn't purge table %s", __FUNCTION__, sqlite3_errmsg(database));
    }
    

    无论如何,您可以通过以下方式阅读此数据:

    - (void)loadRecord
    {
        sqlite3      *database;
        const char   *dbpath = [databasePath UTF8String];
        sqlite3_stmt *statement;
    
        if (sqlite3_open(dbpath, &database) == SQLITE_OK)
        {
            NSString *querySQL = @"SELECT * FROM FINALORDER";
    
            if (sqlite3_prepare_v2(database, [querySQL UTF8String], -1, &statement, NULL) == SQLITE_OK)
            {
                if (sqlite3_step(statement) == SQLITE_ROW)
                {
                    NSString *itemname = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
                    item.text = itemname;
                    //[itemname release]; // if not ARC, uncomment this line
    
                    int qua = sqlite3_column_int(statement, 1);
                    quantity.text = [NSString stringWithFormat:@"%1d", qua];
    
                    double total = sqlite3_column_double(statement, 2);
                    totalcost.text = [NSString stringWithFormat:@"%1.2f", total];
                }
                sqlite3_finalize(statement);
            } else {
                NSLog(@"%s Couldn't prepare; errmsg='%s'", __FUNCTION__, sqlite3_errmsg(database));
            }
            sqlite3_close(database);
        }
    }
    

    注意,

    1. 如果sqlite3_errmsg失败,我已添加了sqlite3_prepare日志语句,并且我已经退出stringWithFormat(因为您没有格式化任何内容)。

    2. 鉴于quantityINTtotalREAL,我正在使用sqlite3_column_text的适当变体检索值,{ {1}}或sqlite3_column_int,视情况而定。

    3. 我推断您没有使用ARC,因此sqlite3_column_double必须有关联的[NSString alloc]release

    4. 最后,在我们的聊天中,您说您收到了一条错误消息(可能是“Undefined Symbols”消息),上面写着:

      autorelease

      这意味着您正在尝试使用OBJC_CLASS_$"_FinalOrder" 的对象类,但您没有在任何地方定义该类。看看它报告此错误的.o文件,并查看相应的.m文件,并在那里查找您对FinalOrder类的使用情况。您显然在某处定义了FinalOrder类接口,但从未定义类实现,或者,如果您有一个,由于某种原因它没有包含在目标的“编译源”列表中,所以仔细检查它在这里:< / p>

      Add compile source

      顺便说一下,确保您的数据库位于FinalOrder文件夹中,而不是尝试在项目的包中打开数据库的副本(因为这是只读的)。如果您的数据库中包含数据库的副本,只需检查您是否已将其存储在Documents文件夹中,如果没有,请将其从包中复制到Documents文件夹。