2

我有一个名为 VegQuantity 的视图控制器,它执行 totalcost=(quantity*cost of the dish) 并将 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);
}

最终视图控制器 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 之前一直收到这个错误,称为预期表达式,我在 viewdidload 中编写这段代码是否正确?我在最终视图控制器中没有任何按钮 我在名为 Restaurant 的视图控制器中有一个名为 order 的按钮,它实际上向我显示最终视图控制器..我应该在最终视图控制器中再次搜索 db 文件,我很抱歉问题似乎有点含糊,但简而言之,我只想知道如何检索我在 VegQuantity 视图控制器中插入的数据并将其显示到最终视图控制器中,谢谢

4

1 回答 1

0

我相信问题一定出在定义FinalOrder里面,根据错误信息,看起来好像已经被定义为一个类,而不是一个sqlite3 *变量。鉴于您使用数据库的范围仅限于这两种方法,我建议sqlite3 *在该范围内定义 a 并使用它,例如:

- (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使用?占位符的语句,然后用于sqlite3_bind_text将值绑定到该语句。这样,如果有人输入了一个包含引号的值,插入语句仍然可以工作(您的原始实现会崩溃和/或容易受到 SQL 注入攻击)。

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

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

顺便说一句,这会调用一个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. 鉴于quantitywasINTtotalwas REAL,我将酌情使用 , 或 的适当变体来sqlite3_column_text检索sqlite3_column_intsqlite3_column_double

  3. 我推断您没有使用 ARC,因此,[NSString alloc]必须有一个关联的releaseor autorelease

最后,在我们的聊天中,您说您收到了一条错误消息(可能是“未定义符号”消息),内容如下:

OBJC_CLASS_$"_FinalOrder"

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

添加编译源

最后,顺便说一句,确保您的数据库在Documents文件夹中,而不是试图打开项目包中的数据库副本(因为这是只读的)。如果您的包中有数据库的副本,只需检查Documents文件夹中是否已经有它,如果没有,请将其从包中复制到Documents文件夹中。

于 2012-08-27T17:35:26.070 回答