我可以将这两个查询结合起来吗?
我收到第二个查询中找不到表的错误,我认为它与第一个查询中的一些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);
感谢
答案 0 :(得分:1)
也许你在声明的这一部分有错误:
SELECT key
FROM recipes
WHERE name = Monday.recipe_name
答案 1 :(得分:1)
有几点意见:
您可能不希望使用stringWithFormat
为查询提供参数。如果食谱是“Pat's Infamous Cookies”怎么办?该撇号将被解释为终止您的字符串,您的准备功能将失败。您应该在SQL中使用?
占位符并绑定值。请参阅SQLite文档的section 3。
虽然我建议您使用上面的sqlite3_bind_text
函数,但实际上您正在调用sqlite3_bind_text
并将其传递给数据库文件。这
没有意义,因为您没有任何?
个占位符来绑定此值;以及
我不确定你为什么要将它传递给数据库的路径。
这个电话看起来似乎不太可行。如果您查看现有sqlite_bind_text
来电的退货代码,我会打赌它不是SQLITE_OK
。
如果您的sqlite3_prepare_v2
调用失败(这是您在优化SQL时常见的失败点),那么您就不会记录sqlite3_errmsg
。在sqlite3_errmsg
失败后得到的sqlite3_prepare_v2
是您将获得的最有用的错误消息之一(它将准确地告诉您SQL的错误)。如果sqlite3_errmsg
未返回sqlite3_prepare_v2
,请务必检查SQLITE_OK
。
因此可能会产生:
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
成为一列。但你所拥有的应该是有效的,但它只是一种不寻常的结构。