SQLite sqlite3_prepare_v2 没有错误但也不好

发布于 2024-11-05 22:00:56 字数 2135 浏览 1 评论 0原文

嘿伙计们,我只是在玩 SQLite,所以这对我来说是新的。我有一个可以保存和查找人员数据的视图。保存功能和查找功能完美运行。现在,我有了一个带有 tableView 的新视图。我想获取联系人表中的所有人员并用它填充列表。

到目前为止,我已经得到:

-(void)viewWillAppear:(BOOL)animated {
    const char *dbpath = [databasePath UTF8String];
    sqlite3_stmt *statement;

    if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
    {
        NSLog(@"Opened DB");
        NSString *querySQL = [NSString stringWithFormat:@"SELECT name FROM contacts"];

        const char *query_stmt = [querySQL UTF8String];
        NSLog(@"could not prepare statement: %s\n", sqlite3_errmsg(contactDB));

        if (sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
        //if (sqlite3_step(query_stmt) == SQLITE_DONE)
        {
            //NSLog(@"SQLite OK");
            NSLog(@"SQLite ok");
            //if (sqlite3_step(statement) == SQLITE_ROW)
            //{
                while(sqlite3_step(statement) == SQLITE_ROW) {
                    NSLog(@"SQLite ROW");
                    NSString *person = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
                    [personsList addObject:person];
                }
            //} else {
            //    NSLog(@"Emtpy list");
            //}
            sqlite3_finalize(statement);
        }
        sqlite3_close(contactDB);
    }
    NSLog(@"Calling reload");
    NSLog(@"%@", personsList);
    [tabelView reloadData];
}

这一切都在 viewWillAppear 中。当视图加载并完成时,日志显示: 2011-05-06 10:45:26.976 数据库[1412:207] 打开数据库

2011-05-06 10:45:26.978 数据库[1412:207] 无法准备语句:不错误

2011-05-06 10:45:26.979数据库[1412:207] 调用重新加载

2011-05-06 10:45:26.979 数据库[1412:207] (

)

所以看来该语句是不是错误,但 sqlite3_prepare_v2 毕竟不是 SQL_OK。有什么帮助吗?

编辑:在上一个视图中,创建人员的语句是: @"INSERT INTO CONTACTS (姓名、地址、电话) VALUES (\"%@\", \"%@\", \"%@ \")",name.text,address.text,phone.text];

找人语句为:@"SELECT address,phone FROM Contacts WHERE name=\"%@\"" , name.text];

这两个语句起作用并显示数据。

Hey guys, I'm just playing around with SQLite so this is new for me. I've got a view in which persons data can be both saved and found. The save-function and find-function work perfectly. Now, I've got a new view with a tableView in it. I want to get all the persons in the contacts-table and fill the list with it.

Untill now, I've got:

-(void)viewWillAppear:(BOOL)animated {
    const char *dbpath = [databasePath UTF8String];
    sqlite3_stmt *statement;

    if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
    {
        NSLog(@"Opened DB");
        NSString *querySQL = [NSString stringWithFormat:@"SELECT name FROM contacts"];

        const char *query_stmt = [querySQL UTF8String];
        NSLog(@"could not prepare statement: %s\n", sqlite3_errmsg(contactDB));

        if (sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
        //if (sqlite3_step(query_stmt) == SQLITE_DONE)
        {
            //NSLog(@"SQLite OK");
            NSLog(@"SQLite ok");
            //if (sqlite3_step(statement) == SQLITE_ROW)
            //{
                while(sqlite3_step(statement) == SQLITE_ROW) {
                    NSLog(@"SQLite ROW");
                    NSString *person = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
                    [personsList addObject:person];
                }
            //} else {
            //    NSLog(@"Emtpy list");
            //}
            sqlite3_finalize(statement);
        }
        sqlite3_close(contactDB);
    }
    NSLog(@"Calling reload");
    NSLog(@"%@", personsList);
    [tabelView reloadData];
}

This is all in viewWillAppear. When the view is loaded and done, the log says:
2011-05-06 10:45:26.976 database[1412:207] Opened DB

2011-05-06 10:45:26.978 database[1412:207] could not prepare statement: not an error

2011-05-06 10:45:26.979 database[1412:207] Calling reload

2011-05-06 10:45:26.979 database[1412:207] (

)

So it seems the statement isn't an error, but sqlite3_prepare_v2 isn't SQL_OK after all. Any help?

EDIT: In the previous view, the statement for creating a person is: @"INSERT INTO CONTACTS (name, address, phone) VALUES (\"%@\", \"%@\", \"%@\")", name.text, address.text, phone.text];

The statement for finding someone is: @"SELECT address, phone FROM contacts WHERE name=\"%@\"", name.text];

These two statements work and the data is displayed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浪漫人生路 2024-11-12 22:00:56

@joetjah我使用你的代码来获取结果并且工作正常

2011-05-06 16:03:00.076 SQLiteDemo[6454:207] Opened DB
2011-05-06 16:03:09.550 SQLiteDemo[6454:207] could not prepare statement: not an error
2011-05-06 16:03:24.685 SQLiteDemo[6454:207] SQLite ok
2011-05-06 16:03:26.229 SQLiteDemo[6454:207] SQLite ROW
2011-05-06 16:03:28.254 SQLiteDemo[6454:207] SQLite ROW
2011-05-06 16:03:34.461 SQLiteDemo[6454:207] Calling reload
2011-05-06 16:03:35.009 SQLiteDemo[6454:207] (
    rahul,
    sqlite
)


-(void)testFunction{
    const char *dbpath = [databasePath UTF8String];
    sqlite3_stmt *statement;
    sqlite3 *contactDB;
    NSMutableArray *personsList = [[NSMutableArray alloc ] initWithCapacity:0];
    if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
    {
        NSLog(@"Opened DB");
        NSString *querySQL = [NSString stringWithFormat:@"SELECT name FROM contacts"];

        const char *query_stmt = [querySQL UTF8String];
        NSLog(@"could not prepare statement: %s\n", sqlite3_errmsg(contactDB));

        if (sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
            //if (sqlite3_step(query_stmt) == SQLITE_DONE)
        {
            //NSLog(@"SQLite OK");
            NSLog(@"SQLite ok");
            //if (sqlite3_step(statement) == SQLITE_ROW)
            //{
            while(sqlite3_step(statement) == SQLITE_ROW) {
                NSLog(@"SQLite ROW");
                NSString *person = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
                [personsList addObject:person];
            }
            //} else {
            //    NSLog(@"Emtpy list");
            //}
            sqlite3_finalize(statement);
        }
        sqlite3_close(contactDB);
    }
    NSLog(@"Calling reload");
    NSLog(@"%@", personsList);
    //[tabelView reloadData];
}

你可以比较代码,可能的失败点可能是
1]数据未正确保存,因此未获取任何内容。
2]databasePath被设置为空白(当你得到Open Db日志时我对此表示怀疑)

表联系人是使用“CREATE TABLE联系人(姓名文本,年龄整数)”创建的
尝试一次,让我知道它是否有效。

@joetjah I used your code to fetch the results and it worked fine

2011-05-06 16:03:00.076 SQLiteDemo[6454:207] Opened DB
2011-05-06 16:03:09.550 SQLiteDemo[6454:207] could not prepare statement: not an error
2011-05-06 16:03:24.685 SQLiteDemo[6454:207] SQLite ok
2011-05-06 16:03:26.229 SQLiteDemo[6454:207] SQLite ROW
2011-05-06 16:03:28.254 SQLiteDemo[6454:207] SQLite ROW
2011-05-06 16:03:34.461 SQLiteDemo[6454:207] Calling reload
2011-05-06 16:03:35.009 SQLiteDemo[6454:207] (
    rahul,
    sqlite
)


-(void)testFunction{
    const char *dbpath = [databasePath UTF8String];
    sqlite3_stmt *statement;
    sqlite3 *contactDB;
    NSMutableArray *personsList = [[NSMutableArray alloc ] initWithCapacity:0];
    if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
    {
        NSLog(@"Opened DB");
        NSString *querySQL = [NSString stringWithFormat:@"SELECT name FROM contacts"];

        const char *query_stmt = [querySQL UTF8String];
        NSLog(@"could not prepare statement: %s\n", sqlite3_errmsg(contactDB));

        if (sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
            //if (sqlite3_step(query_stmt) == SQLITE_DONE)
        {
            //NSLog(@"SQLite OK");
            NSLog(@"SQLite ok");
            //if (sqlite3_step(statement) == SQLITE_ROW)
            //{
            while(sqlite3_step(statement) == SQLITE_ROW) {
                NSLog(@"SQLite ROW");
                NSString *person = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
                [personsList addObject:person];
            }
            //} else {
            //    NSLog(@"Emtpy list");
            //}
            sqlite3_finalize(statement);
        }
        sqlite3_close(contactDB);
    }
    NSLog(@"Calling reload");
    NSLog(@"%@", personsList);
    //[tabelView reloadData];
}

You can compare the code, The probable point of failure might be
1] data not being saved properly and hence nothing is fetched.
2] databasePath being set to blank (which I doubt as you get Open Db log)

The table contact is created using "CREATE TABLE contacts (name text, age integer)"
try this once and let me know if it works.

谜兔 2024-11-12 22:00:56

试试这个,

-(void)viewWillAppear:(BOOL)animated {

    // Override point for customization after app launch.
    // Setup some globals
    // Get the path to the documents directory and append the databaseName
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    databasePath = [documentsDir stringByAppendingPathComponent:@"contacts.db"];

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

    if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
    {
        NSLog(@"Opened DB");
        NSString *querySQL = [NSString stringWithFormat:@"SELECT name FROM CONTACTS"];
        const char *query_stmt = [querySQL UTF8String];

        NSLog(@"could not prepare statement: %s\n", sqlite3_errmsg(contactDB));

        if (sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
        {
            NSLog(@"SQLite ok");
                while(sqlite3_step(statement) == SQLITE_ROW) {
                    NSLog(@"SQLite ROW");
                    NSString *person = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
                    [personsList addObject:person];
                }
            sqlite3_finalize(statement);
        }
        else
        {
            //NSLog(@"could not prepare statement: %s\n", sqlite3_errmsg(statement));
        }
        sqlite3_close(contactDB);
    }
    NSLog(@"Calling reload");
    NSLog(@"%@", personsList);
    [tabelView reloadData];
}

Try this,

-(void)viewWillAppear:(BOOL)animated {

    // Override point for customization after app launch.
    // Setup some globals
    // Get the path to the documents directory and append the databaseName
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    databasePath = [documentsDir stringByAppendingPathComponent:@"contacts.db"];

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

    if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
    {
        NSLog(@"Opened DB");
        NSString *querySQL = [NSString stringWithFormat:@"SELECT name FROM CONTACTS"];
        const char *query_stmt = [querySQL UTF8String];

        NSLog(@"could not prepare statement: %s\n", sqlite3_errmsg(contactDB));

        if (sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL) == SQLITE_OK)
        {
            NSLog(@"SQLite ok");
                while(sqlite3_step(statement) == SQLITE_ROW) {
                    NSLog(@"SQLite ROW");
                    NSString *person = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
                    [personsList addObject:person];
                }
            sqlite3_finalize(statement);
        }
        else
        {
            //NSLog(@"could not prepare statement: %s\n", sqlite3_errmsg(statement));
        }
        sqlite3_close(contactDB);
    }
    NSLog(@"Calling reload");
    NSLog(@"%@", personsList);
    [tabelView reloadData];
}
独行侠 2024-11-12 22:00:56

我使用了 const char *dbpath = [databasePath UTF8String];,但我忘记将以下代码放在上面:

// Get the documents directory
    NSString *docsDir;
    NSArray *dirPaths;
    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    docsDir = [dirPaths objectAtIndex:0];
    databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"contacts.db"]];
    const char *dbpath = [databasePath UTF8String];

I used const char *dbpath = [databasePath UTF8String];, but I forgot to put the following code above it:

// Get the documents directory
    NSString *docsDir;
    NSArray *dirPaths;
    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    docsDir = [dirPaths objectAtIndex:0];
    databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"contacts.db"]];
    const char *dbpath = [databasePath UTF8String];
戈亓 2024-11-12 22:00:56

这对我有用:

在 didload 函数中创建表,然后添加它(假设您已经声明了其他表视图函数):

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell        

    var selectStatement: OpaquePointer? = nil
    let selectSql = "select * from Inventory where ID = \((indexPath.row + 1))"
    if sqlite3_prepare_v2(Database.database.sqliteDB, selectSql, -1, &selectStatement, nil) == SQLITE_OK{
        if sqlite3_step(selectStatement) == SQLITE_ROW {

            let nameItem = sqlite3_column_text(selectStatement, 1)
            let price = sqlite3_column_double(selectStatement, 2)
            let quantity = sqlite3_column_int(selectStatement, 3)

            let nameString = String(cString: nameItem!)
            let priceString = String(format: "%.1f",price)
            let quantityString = String(quantity)

            cell.itemName.text = nameString
            cell.itemPrice.text = priceString
            cell.itemQuantity.text = quantityString

        }
    }

    return cell
}

This worked for me:

create the table in your didload functions and then add this in (assuming you have declared the other table view functions):

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell        

    var selectStatement: OpaquePointer? = nil
    let selectSql = "select * from Inventory where ID = \((indexPath.row + 1))"
    if sqlite3_prepare_v2(Database.database.sqliteDB, selectSql, -1, &selectStatement, nil) == SQLITE_OK{
        if sqlite3_step(selectStatement) == SQLITE_ROW {

            let nameItem = sqlite3_column_text(selectStatement, 1)
            let price = sqlite3_column_double(selectStatement, 2)
            let quantity = sqlite3_column_int(selectStatement, 3)

            let nameString = String(cString: nameItem!)
            let priceString = String(format: "%.1f",price)
            let quantityString = String(quantity)

            cell.itemName.text = nameString
            cell.itemPrice.text = priceString
            cell.itemQuantity.text = quantityString

        }
    }

    return cell
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文