我能否以某种方式组合这两个查询?
我在第二个查询中收到表未找到的错误,我认为它与第一个查询中的一些 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);
谢谢
最佳答案
一些观察:
您可能不想使用
stringWithFormat
为您的查询提供参数。如果食谱是“Pat's Infamous Cookies”怎么办?该撇号将被解释为终止您的字符串,并且您的准备功能将失败。您应该在 SQL 中使用?
占位符并绑定(bind)值。参见 section 3 SQLite 文档。虽然我建议您使用上面的
sqlite3_bind_text
函数,但您实际上是在调用sqlite3_bind_text
并将数据库文件的路径传递给它。那个对于您的 SQL 没有意义,因为您没有任何
?
占位符来绑定(bind)此值;和我完全不确定您为什么要将数据库路径传递给它。
那个电话似乎不太可能奏效。如果您检查现有
sqlite_bind_text
调用的返回码,我敢打赌它不是SQLITE_OK
。如果您的
sqlite3_prepare_v2
调用失败(这是优化 SQL 时常见的失败点),您不会记录sqlite3_errmsg
.在sqlite3_prepare_v2
失败后收到的sqlite3_errmsg
是您将收到的最有用的错误消息之一(它会准确地告诉您 SQL 出了什么问题)。如果sqlite3_prepare_v2
没有返回SQLITE_OK
,请务必检查sqlite3_errmsg
。
因此可能会产生:
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
作为该表格中的一列。但是你所拥有的应该可以工作,但这只是一个不寻常的结构。
关于ios - 合并两个 sqlite3 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18619612/