我有两个数据库。
我尝试将两个数据库中的select组合并将数据填充到object。我的方法是这样的:
-(NSMutableArray*)returnSubCountries
{
NSString *path = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:databaseName];
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *userDB = [documentsDir stringByAppendingPathComponent:user_data];
NSMutableArray *subCountiresArr=[[NSMutableArray alloc]init];
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK)
{
/*const char *sqlSubCountries="SELECT subCountryID,subCountryName,subCountryComment,image,priority,hasRegions,navigationKey\
FROM subCountries\
ORDER BY priority ASC";*/
const char *sqlSubCountries="SELECT subCountryID,subCountryName,subCountryComment,image,priority,hasRegions,navigationKey,usdb.quantity\
attach database 'userDB' as usdb\
INNER JOIN usdb on subCountries.subCountryID=usdb.refID\
FROM subCountries\
ORDER BY priority ASC";
sqlite3_stmt *statement;
int sqlResult = sqlite3_prepare_v2(database, sqlSubCountries, -1, &statement, NULL);
if ( sqlResult== SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
SubCountry *sbCountryObj=[[SubCountry alloc]init];
sbCountryObj.subCountryID=sqlite3_column_int(statement, 0);
char *subCountryName=(char *)sqlite3_column_text(statement, 1);
char *subCountryComment=(char *)sqlite3_column_text(statement, 2);
char *image=(char *)sqlite3_column_text(statement, 3);
sbCountryObj.priority=sqlite3_column_int(statement, 4);
sbCountryObj.hasRegions=(sqlite3_column_int(statement, 5)==1);
sbCountryObj.navigationKey=sqlite3_column_int(statement, 6);
sbCountryObj.quantity=sqlite3_column_int(statement, 7);
sbCountryObj.subCountryName=(subCountryName)?[NSString stringWithUTF8String:subCountryName]: @"";
sbCountryObj.subCountryComment=(subCountryComment)?[NSString stringWithUTF8String:subCountryComment]: @"";
sbCountryObj.image=(image)?[NSString stringWithUTF8String:image]: @"";
[subCountiresArr addObject:sbCountryObj];
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
}
else
{
//[self dbConnectionError];
}
return subCountiresArr;
}
我一定是做错了。任何帮助深表感谢。感谢名单。
编辑:
-(NSMutableArray*)returnSubCountries
{
NSString *path = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:databaseName];
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *userDB = [documentsDir stringByAppendingPathComponent:user_data];
NSMutableArray *subCountiresArr=[[NSMutableArray alloc]init];
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK)
{
/*const char *sqlSubCountries="SELECT subCountryID,subCountryName,subCountryComment,image,priority,hasRegions,navigationKey\
FROM subCountries\
ORDER BY priority ASC";*/
NSString *userDBName = [NSString stringWithFormat:@"attach database '%@' as usdb", userDB];
const char *sqlAttachedDatabase = [userDBName UTF8String];
const char *sqlSubCountries="SELECT subCountryID,subCountryName,subCountryComment,image,priority,hasRegions,navigationKey,usdb.quantity\
sqlAttachedDatabase userDB as usdb\
INNER JOIN usdb on subCountries.subCountryID=usdb.refID\
FROM subCountries\
ORDER BY priority ASC";
sqlite3_stmt *statement;
int sqlResult = sqlite3_prepare_v2(database, sqlSubCountries, -1, &statement, NULL);
if ( sqlResult== SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
SubCountry *sbCountryObj=[[SubCountry alloc]init];
sbCountryObj.subCountryID=sqlite3_column_int(statement, 0);
char *subCountryName=(char *)sqlite3_column_text(statement, 1);
char *subCountryComment=(char *)sqlite3_column_text(statement, 2);
char *image=(char *)sqlite3_column_text(statement, 3);
sbCountryObj.priority=sqlite3_column_int(statement, 4);
sbCountryObj.hasRegions=(sqlite3_column_int(statement, 5)==1);
sbCountryObj.navigationKey=sqlite3_column_int(statement, 6);
sbCountryObj.quantity=sqlite3_column_int(statement, 7);
sbCountryObj.subCountryName=(subCountryName)?[NSString stringWithUTF8String:subCountryName]: @"";
sbCountryObj.subCountryComment=(subCountryComment)?[NSString stringWithUTF8String:subCountryComment]: @"";
sbCountryObj.image=(image)?[NSString stringWithUTF8String:image]: @"";
[subCountiresArr addObject:sbCountryObj];
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
else
{
NSLog(@"%s: prepare failed: %s", __FUNCTION__, sqlite3_errmsg(database));
}
}
else
{
//[self dbConnectionError];
}
return subCountiresArr;
}
答案 0 :(得分:1)
您应该执行以下操作:
答案 1 :(得分:1)
您在SQL中将数据库路径指定为userDB
,但这不是数据库文件的名称。也就是说,其中包含完整路径名的变量的名称,但您可能实际上必须使用该文件名构建SQL。例如:
NSString *sql = [NSString stringWithFormat:@"attach database '%@' as usdb", userDB];
const char *sqlAttachedDatabase = [sql UTF8String];
执行。然后,作为单独的语句,您可以执行使用usdb
别名的SELECT SQL。当你完成后,分离数据库。
此外,我注意到您正在检查结果是否为SQLITE_OK
(这是好的)。但是,如果不是,那么您没有显示任何诊断信息。例如,您的SQL错误,但您没有显示有意义的错误消息。因此,如果sqlite3_prepare_v2
未能返回SQLITE_OK
,您应该:
NSLog(@"%s: prepare failed: %s", __FUNCTION__, sqlite3_errmsg(database));
如果你在遇到错误时这样做,你就能弄明白什么是错的。没有它,你就会失明。
一个工作示例,我的“作者”数据库位于捆绑包中,而我的“book”数据库位于Documents
中:
int rc;
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *bookFilename = [docsPath stringByAppendingPathComponent:@"book.sqlite"];
NSString *authorFilename = [[NSBundle mainBundle] pathForResource:@"author" ofType:@"sqlite"];
sqlite3 *database;
if ((rc = sqlite3_open([authorFilename UTF8String], &database)) != SQLITE_OK)
{
NSLog(@"%s: open failed: %s (%d)", __FUNCTION__, sqlite3_errmsg(database), rc);
return;
}
NSString *sql = [NSString stringWithFormat:@"attach database '%@' as userdb;", bookFilename];
if ((rc = sqlite3_exec(database, [sql UTF8String], NULL, NULL, NULL)) != SQLITE_OK)
NSLog(@"%s: attach failed: %s (%d)", __FUNCTION__, sqlite3_errmsg(database), rc);
sqlite3_stmt *statement;
sql = @"select book.*, author.* from userdb.book inner join author on author_id = book_author_id;";
if ((rc = sqlite3_prepare_v2(database, [sql UTF8String], -1, &statement, NULL)) != SQLITE_OK)
NSLog(@"%s: prepare failed: %s (%d)", __FUNCTION__, sqlite3_errmsg(database), rc);
while ((rc = sqlite3_step(statement)) == SQLITE_ROW)
{
// do whatever you want row by row
NSLog(@"Row");
}
if (rc != SQLITE_DONE)
NSLog(@"%s: step failed: %s (%d)", __FUNCTION__, sqlite3_errmsg(database), rc);
sqlite3_finalize(statement);
sql = @"detach database userdb;";
if ((rc = sqlite3_exec(database, [sql UTF8String], NULL, NULL, NULL)) != SQLITE_OK)
NSLog(@"%s: detach failed: %s (%d)", __FUNCTION__, sqlite3_errmsg(database), rc);
sqlite3_close(database);