我試圖在插入一些數據後從數據庫中獲取數據時遇到問題。我無法從數據庫中選擇任何行。插入數據庫後無法選擇行
數據庫中有條目,但我無法得到任何結果。
我註釋掉的AppDelegate ::應用這一行:didFinishWithOptions
[dbAccess importWithDelegate:result];
,一切工作就好了。但是我找不到解決這個問題的辦法。 我希望你能幫助我。
DatabaseAccess-Class。
#import "KejithDatabaseAccess.h"
#import "KejithEntryQueryDelegate.h"
@interface KejithDatabaseAccess(){
sqlite3 *db;
NSString *writableDatabase;
sqlite3_stmt *statement;
}
@end
@implementation KejithDatabaseAccess
-(id)init
{
if((self = [super init]))
{
// initialize database and store in _db
}
return self;
}
-(void)initializeDatabase
{
[self createEditableDatabase];
// open the database connection
if(sqlite3_open([writableDatabase UTF8String], &db) == SQLITE_OK){
NSLog(@"Database: Connection was opened successfully");
} else {
// if something went wrong clean everything up
sqlite3_close(db);
NSAssert1(0, @"Database: Failed to open database connection. Error: '%s'", sqlite3_errmsg(db));
}
}
-(void)closeDatabase
{
if(sqlite3_close(db) != SQLITE_OK){
NSAssert1(0, @"Database: Failed to close database connection. Error: '%s'", sqlite3_errmsg(db));
}
}
-(void)createEditableDatabase
{
BOOL success;
NSError *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
// create writable database and store path for later use
writableDatabase = [documentsDir stringByAppendingPathComponent:@"main-rw.db"];
success = [fileManager fileExistsAtPath: writableDatabase];
// if writable database already exists return
if(success) return;
// the editable database does not exist
// copy the default DB to the application
// documents directory
NSString *defaultPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"main.db"];
success = [fileManager copyItemAtPath:defaultPath toPath:writableDatabase error:&error];
if(!success){
NSAssert1(0, @"Database: Failed to create writable database file: '%@'.", [error localizedDescription]);
}
}
-(NSMutableArray *)queryWithDelegate
{
[self initializeDatabase];
// do we have an delegate?
if(![self delegate])
return nil;
NSMutableArray *result = [[self delegate] query:db];
[self closeDatabase];
return result;
}
-(void)importWithDelegate:(NSMutableArray *)collection
{
[self initializeDatabase];
[[self delegate] import:collection into:db];
sqlite3_finalize(statement);
[self closeDatabase];
}
-(sqlite3 *)getWritableDatabase
{
return db;
}
@end
數據庫代表級
#import "KejithEntryQueryDelegate.h"
#import "KejithEntry.h"
@interface KejithEntryQueryDelegate()
@property sqlite3 *database;
@end
@implementation KejithEntryQueryDelegate
@synthesize sql;
@synthesize statement;
-(id)init
{
if((self = [super init])){
[self initSQL];
}
return self;
}
-(void)initSQL
{
sql = "SELECT _id, entry_title, entry_description, entry_phone, entry_fax, entry_email, entry_website FROM entry";
}
-(NSMutableArray *)query:(sqlite3 *)database
{
// store database
[self setDatabase:database];
// initialize array to store found objects
NSMutableArray *entries = [[NSMutableArray alloc] init];
// prepare sql statement
int sqlResult = sqlite3_prepare_v2(database, sql, -1, &statement, NULL);
if(sqlResult == SQLITE_OK){
while(sqlite3_step(statement) == SQLITE_ROW){
// allocate object to store row
KejithEntry *entry = [[KejithEntry alloc] init];
// get data from columns
NSMutableString *title = [NSMutableString stringWithString:
[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 1)]];
NSMutableString *description = [NSMutableString stringWithString:
[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 2)]];
NSMutableString *phone = [NSMutableString stringWithString:
[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 3)]];
NSMutableString *fax = [NSMutableString stringWithString:
[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 4)]];
NSMutableString *email = [NSMutableString stringWithString:
[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 5)]];
NSMutableString *website = [NSMutableString stringWithString:
[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 5)]];
// set data in object
[entry setId:[NSNumber numberWithInt: sqlite3_column_int(statement, 0)]];
[entry setTitle:title];
[entry setDescription:description];
[entry setPhone:phone];
[entry setFax:fax];
[entry setEmail:email];
[entry setWebsite:website];
// put object into array
[entries addObject:entry];
}
// finalize the statement to release its resources
sqlite3_finalize(statement);
} else {
// log errors
NSLog(@"Database: Problem Occured in KejithEntryQueryDelegate.m");
NSLog(@"Database: Result Code: %d", sqlResult);
NSLog(@"Database: SQL-Error: %s", sqlite3_errmsg(database));
}
return entries;
}
-(void)import:(NSMutableArray *)collection into:(sqlite3 *)database
{
if([collection count] == 0)
return;
for(KejithEntry *entry in collection){
[self importEntry:entry into:database];
}
}
-(void)importEntry:(KejithEntry *)entry into:(sqlite3 *)database
{
sql = "INSERT INTO entry (entry_id, entry_title, entry_description, entry_phone, entry_fax, entry_email, entry_website, enty_latitude, entry_longitude, entry_category_id) \
VALUES \
(0,?,?,?,?,?,?,0,0,0);";
int sqlResult = sqlite3_prepare_v2(database, sql, -1, &statement, NULL);
sqlite3_bind_text(statement, 1, [[entry title] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 2, [[entry getDescription] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 3, [[entry phone] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 4, [[entry fax] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 5, [[entry email] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 6, [[entry website] UTF8String], -1, SQLITE_STATIC);
if(sqlite3_step(statement) != SQLITE_DONE){
NSLog(@">> Database: Failed to insert into Database");
NSLog(@"SQL Error Message: %s", sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
}
@end
的AppDelegate ::應用:didFinishWithLaunchingOptions
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
// create delegate for entry xml parsing
id delegate = [[KejithEntryXmlDelegate alloc] init];
KejithXmlParser *parser = [[KejithXmlParser alloc] initWithUrl:[[NSURL alloc] initWithString:entryXmlUrl]];
KejithDatabaseAccess *dbAccess = [[KejithDatabaseAccess alloc] init];
KejithEntryQueryDelegate *dbEntryDelegate = [[KejithEntryQueryDelegate alloc] init];
// set delegate to parse xml file
[parser setDelegate:delegate];
// set delegate to query data to/from database
[dbAccess setDelegate:dbEntryDelegate];
// get results of xml parsing
NSMutableArray *result = [parser parse];
NSLog(@"Count of ParseResult: %d", [result count]);
[dbAccess importWithDelegate:result];
NSLog(@"Count of DatabaseResult: %d", [[dbAccess queryWithDelegate] count]);
return YES;
}
控制檯 - 輸出而不[DBACCESS importWithDelegate:結果]註釋:
2013-12-08 15:59:44.035 staedteApp[30202:70b] Database: Connection was opened successfully
2013-12-08 15:59:44.048 staedteApp[30202:70b] Database: Connection was opened successfully
2013-12-08 15:59:44.049 staedteApp[30202:70b] Count of DatabaseResult: 0
控制檯-輸出與[DBACCESS importWithDelegate:結果]註釋:
2013-12-08 16:17:18.084 staedteApp[30267:70b] Database: Connection was opened successfully
2013-12-08 16:17:18.091 staedteApp[30267:70b] Count of DatabaseResult: 50
EDIT#1 ----- 更新KejithEntryQueryDelegate :: importEntry:進
-(void)importEntry:(KejithEntry *)entry into:(sqlite3 *)database
{
sql = "INSERT INTO entry (entry_id, entry_title, entry_description, entry_phone, entry_fax, entry_email, entry_website, enty_latitude, entry_longitude, entry_category_id) \
VALUES \
(0,?,?,?,?,?,?,0,0,0);";
int sqlResult = sqlite3_prepare_v2(database, sql, -1, &statement, NULL);
if(sqlResult != SQLITE_DONE){
sqlite3_bind_text(statement, 1, [[entry title] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 2, [[entry getDescription] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 3, [[entry phone] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 4, [[entry fax] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 5, [[entry email] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 6, [[entry website] UTF8String], -1, SQLITE_STATIC);
int sqlStepResult;
if((sqlStepResult = sqlite3_step(statement)) != SQLITE_DONE){
NSLog(@">> Database: Failed to insert into Database");
NSLog(@"SQL Error Message: %s", sqlite3_errmsg(database));
NSLog(@"SQL Step Result: %d", sqlStepResult);
}
} else {
NSLog(@"Database: Problem Occured in KejithEntryQueryDelegate.m step");
NSLog(@"Database: Result Code: %d", sqlResult);
NSLog(@"Database: SQL-Error: %s", sqlite3_errmsg(database));
}
sqlite3_finalize(statement);
}
嗨,羅布,感謝您的回答。首先:對,就是那種好奇的行爲。我試過你提到的一切。我編輯了我的帖子「編輯#1」。控制檯輸出仍然相同。你提到的最終版本只是一個隨機的嘗試,但在我的問題之後被刪除。 – kejith
@kejith在那個修改過的SQL中,準備好後,你有'if(sqlResult!= SQLITE_DONE)...',我想你的意思是'if(sqlResult == SQLITE_OK)...'。 'SQLITE_DONE'只是來自step函數的響應。但是抱歉,更廣泛的問題並沒有在我身上跳躍。如果您在某處(例如github,dropbox)上傳項目,我很高興看一看。 – Rob
感謝您的幫助。請耐心等待。這是我第一次用iOS和Objective C進行開發。我刪除了我以前的評論。 – kejith