结合两个sqlite3查询

时间:2013-09-04 16:52:36

标签: ios objective-c sqlite

我可以将这两个查询结合起来吗?

我收到第二个查询中找不到表的错误,我认为它与第一个查询中的一些sqlite调用有关。

NSString *dayName = del.dayName;
int rowCount = del.tableRowNumber;

NSString *sqLiteDb = [[NSBundle mainBundle] pathForResource:@"banklist" ofType:@"sqlite3"];

if(sqlite3_open([sqLiteDb UTF8String], &_database) == SQLITE_OK)
{
    NSString *sqlStatement = [NSString stringWithFormat:@"UPDATE %@ SET recipe_name='%@' WHERE cell_id='%i'",dayName, info.name, rowCount];
    sqlite3_stmt *compiledStatement;

    if(sqlite3_prepare_v2(_database, [sqlStatement UTF8String] , -1, &compiledStatement, NULL) == SQLITE_OK)
    {
        sqlite3_bind_text( compiledStatement, 1, [sqLiteDb UTF8String], -1, SQLITE_TRANSIENT);
    }
    if(sqlite3_step(compiledStatement) != SQLITE_DONE )
    {
        NSLog( @"Save Error: %s", sqlite3_errmsg(_database) );
    }
    else
    {
        sqlite3_reset(compiledStatement);
    }

    sqlite3_finalize(compiledStatement);


    NSString *sqlStatement2 = [NSString stringWithFormat:@"UPDATE %@ SET recipe_id = (SELECT key FROM recipes WHERE name = Monday.recipe_name)",dayName];
    sqlite3_stmt *compiledStatement2;

    if(sqlite3_prepare_v2(_database, [sqlStatement2 UTF8String] , -1, &compiledStatement2, NULL) == SQLITE_OK)
    {
        sqlite3_bind_text( compiledStatement2, 1, [sqLiteDb UTF8String], -1, SQLITE_TRANSIENT);
    }
    if(sqlite3_step(compiledStatement2) != SQLITE_DONE )
    {
        NSLog( @"Save Error: %s", sqlite3_errmsg(_database) );
    }
    else
    {
        sqlite3_reset(compiledStatement2);
    }

    sqlite3_finalize(compiledStatement2);
}

sqlite3_close(_database);

感谢

2 个答案:

答案 0 :(得分:1)

也许你在声明的这一部分有错误:

SELECT key
FROM recipes
WHERE name = Monday.recipe_name

答案 1 :(得分:1)

有几点意见:

  1. 您可能不希望使用stringWithFormat为查询提供参数。如果食谱是“Pat's Infamous Cookies”怎么办?该撇号将被解释为终止您的字符串,您的准备功能将失败。您应该在SQL中使用?占位符并绑定值。请参阅SQLite文档的section 3

  2. 虽然我建议您使用上面的sqlite3_bind_text函数,但实际上您正在调用sqlite3_bind_text并将其传递给数据库文件。这

      鉴于您的SQL,
    • 没有意义,因为您没有任何?个占位符来绑定此值;以及

    • 我不确定你为什么要将它传递给数据库的路径。

    这个电话看起来似乎不太可行。如果您查看现有sqlite_bind_text来电的退货代码,我会打赌它不是SQLITE_OK

  3. 如果您的sqlite3_prepare_v2调用失败(这是您在优化SQL时常见的失败点),那么您就不会记录sqlite3_errmsg。在sqlite3_errmsg失败后得到的sqlite3_prepare_v2是您将获得的最有用的错误消息之一(它将准确地告诉您SQL的错误)。如果sqlite3_errmsg未返回sqlite3_prepare_v2,请务必检查SQLITE_OK

  4. 因此可能会产生:

    if(sqlite3_open([sqLiteDb UTF8String], &_database) == SQLITE_OK)
    {
        NSString *sqlStatement = [NSString stringWithFormat:@"UPDATE %@ SET recipe_name=? WHERE cell_id=?",dayName];
        sqlite3_stmt *compiledStatement;
    
        if(sqlite3_prepare_v2(_database, [sqlStatement UTF8String] , -1, &compiledStatement, NULL) != SQLITE_OK)
        {
            NSLog(@"%s: prepare failed: %s", __FUNCTION__, sqlite3_errmsg(_database));
            sqlite3_close(_database);
            return;
        }
    
        if (sqlite3_bind_text( compiledStatement, 1, [info.name UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
        {
            NSLog(@"%s: bind_text failed: %s", __FUNCTION__, sqlite3_errmsg(_database));
            sqlite3_finalize(compiledStatement);
            sqlite3_close(_database);
            return;
        }
    
        if (sqlite3_bind_int( compiledStatement, 2, rowCount) != SQLITE_OK)
        {
            NSLog(@"%s: bind_int failed: %s", __FUNCTION__, sqlite3_errmsg(_database));
            sqlite3_finalize(compiledStatement);
            sqlite3_close(_database);
            return;
        }
    
        if (sqlite3_step(compiledStatement) != SQLITE_DONE )
        {
            NSLog(@"Save Error: %s", sqlite3_errmsg(_database) );
            sqlite3_finalize(compiledStatement);
            sqlite3_close(_database);
            return;
        }
    
        // you don't need this unless you're going to reuse that prepared statement, which you aren't
        //
        //else
        //{
        //    sqlite3_reset(compiledStatement);
        //}
    
        sqlite3_finalize(compiledStatement);
    
        // did you really mean to hardcode "Monday" in this SQL?
    
        NSString *sqlStatement2 = [NSString stringWithFormat:@"UPDATE %@ SET recipe_id = (SELECT key FROM recipes WHERE name = Monday.recipe_name)",dayName];
        sqlite3_stmt *compiledStatement2;
    
        if(sqlite3_prepare_v2(_database, [sqlStatement2 UTF8String] , -1, &compiledStatement2, NULL) != SQLITE_OK)
        {
            NSLog(@"%s: prepare 2 failed: %s", __FUNCTION__, sqlite3_errmsg(_database));
            sqlite3_close(_database);
            return;
        }
        if(sqlite3_step(compiledStatement2) != SQLITE_DONE )
        {
            NSLog( @"Save 2 Error: %s", sqlite3_errmsg(_database) );
        }
    
        // again, not needed
        //
        //else
        //{
        //    sqlite3_reset(compiledStatement);
        //}
    
        sqlite3_finalize(compiledStatement2);
    }
    
    sqlite3_close(_database);
    

    我必须承认,我并不是在为构建SQL而动态提供表名的数据模型而疯狂。我宁愿看到一个包含所有日子的单个表,并在该表中使dayName成为一列。但你所拥有的应该是有效的,但它只是一种不寻常的结构。