【发布时间】:2013-10-16 18:04:01
【问题描述】:
我目前正在尝试调用本地化的 sqlite3 数据库以从多个表中加载特定值。第一个请求是向 fetchAllAmmoForDiamter 发出的,后者又调用 fetchBCForAllAmmoModels。我可以验证我的请求语句是否正确,因为在 SQLite Database Browser 2.0 中将其作为查询语句运行时,它会返回正确的值。但是,在 iOS 应用程序上运行它时,它会为所有内容返回 0。有人知道为什么会这样吗?
- (NSArray *)fetchAllAmmoForDiameter:(NSNumber *)d
{
sqlite3 *database;
NSMutableArray *allAmmoModels = [NSMutableArray new];
NSString *db = [[NSBundle mainBundle] pathForResource:@"bulletlib" ofType:@"sqlite3"];
if (sqlite3_open([db UTF8String], &database) == SQLITE_OK) {
double diameter = [d doubleValue];
NSString *query = [NSString stringWithFormat:@"SELECT _id, manufacturer_id, weight, length, model, hide_bcs FROM bullets WHERE diameter=%f ORDER BY diameter, manufacturer_id ASC", diameter ];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
int uniqueID = sqlite3_column_int(statement, 0);
int manufactureID = sqlite3_column_int(statement, 1);
double weight = sqlite3_column_double(statement, 2);
double length = sqlite3_column_double(statement, 3);
char *model = (char *)sqlite3_column_text(statement, 4);
// NSLog(@"%d,%d,%f,%f %f, %s", uniqueID, manufactureID, diameter, weight, length, model );
NSString *modelName = [NSString stringWithUTF8String:model];
AmmoDatabaseModel *dbModel = [[AmmoDatabaseModel alloc]initWithUniqueId:uniqueID manufactureId:manufactureID diameter:diameter weight:weight length:length andModel:modelName];
[allAmmoModels addObject:dbModel];
}
} else {
printf( "could not prepare statemnt: %s\n", sqlite3_errmsg(database) );
}
sqlite3_finalize(statement);
sqlite3_close(database);
[self fetchBCForAllAmmoModels:allAmmoModels];
}
return allAmmoModels;
}
-(void)fetchBCForAllAmmoModels:(NSArray *)ammoModels
{
for (AmmoDatabaseModel *ammoModel in ammoModels ){
ammoModel.ballisticCoefficients = [self fetchBCForAmmoModel:ammoModel];
}
}
-(NSArray *)fetchBCForAmmoModel:(AmmoDatabaseModel *)ammoModel
{
NSMutableArray *bcModels = [NSMutableArray new];
sqlite3 *database;
NSString *db = [[NSBundle mainBundle] pathForResource:@"bulletlib" ofType:@"sqlite3"];
if (sqlite3_open([db UTF8String], &database) == SQLITE_OK) {
NSString *query = [NSString stringWithFormat:@"SELECT drag_func, bc, minvel FROM bullet_bcs WHERE bullet_id=%i", [ammoModel.uniqueID intValue]];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
int dragFunction = sqlite3_column_double(statement, 1);
double bc = sqlite3_column_double(statement, 2);
int minvel = sqlite3_column_int(statement, 3);
BallisticCoefficientDatabaseModel *bcModel = [[BallisticCoefficientDatabaseModel alloc] initWithDragFunction:dragFunction coefficient:bc minimumVelocity:minvel];
[bcModels addObject:bcModel];
}
} else {
printf( "could not prepare statemnt: %s\n", sqlite3_errmsg(database) );
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
return bcModels;
}
【问题讨论】:
-
您没有处理 sqlite3_prepare_v2 调用的 else 语句。你确定那里没有发生错误吗?您可以添加 else 并尝试 NSLog 错误吗?如果出现错误,根据您的代码逻辑,您将返回一个空数组,这似乎正在发生。
-
我会牢记这一点并做到这一点。我没有在 else 中测试 via 的唯一原因是它确实进入了循环。
-
我更新了如上所示的代码并运行它。没有错误打印到控制台,现在数据库在结束或发出下一个 SQL 请求之前肯定是关闭的。
-
那么接下来我将在控制台中打开数据库以确认数据实际上存储在数据库中。您可以使用您的数据库路径 nslog 您拥有的 db 变量,cd 进入目录,然后运行“sqlite3 bulletlib.db”。在 sqlite3 页面中,运行 .dump 命令。如果数据确实存在,那么问题肯定是您的选择查询。
-
现在你关闭数据库,即使它没有打开。
标签: ios sql objective-c database sqlite