我在我的服务器中存储了详细信息。我使用服务器URL获取详细信息并存储到数据库表。我插入失败的NSLog。我在文件夹中有2个sqlite文件。在copyItemAtPath之后,即时写入该文件。
代码:
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSError *err;
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"db5" ofType:@"sqlite"];
//NSLog(@"bundlePath %@", bundlePath);
//call update function to check any data updated,
//if there is a version difference
//update the data base with all the required fileds.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//NSLog(@"docs dir is %@", documentsDirectory);
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:@"db1.sqlite"];
// [fileMgr copyItemAtPath:bundlePath toPath:appFile error:&err];
BOOL success = [fileMgr copyItemAtPath:bundlePath toPath:appFile error:&err];
if (!success) {
NSLog(@"Failed to create writable database file with message '%@'.", [err localizedDescription]);
}
NSURL *URL = [NSURL URLWithString:@"http://myserver.net/projects/mobile/jsonstring.php"];
NSError *error;
NSString *stringFromFileAtURL = [[NSString alloc]
initWithContentsOfURL:URL
encoding:NSUTF8StringEncoding
error:&error];
//NSLog(@"response is %@", stringFromFileAtURL);
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"db1.sqlite"];
//NSLog(@"filepath %@",path);
//array
NSArray *userData = [stringFromFileAtURL JSONValue];
[stringFromFileAtURL release];
// NSLog(@"userdata is %@", userData);
int i = 0;
BOOL notExist = TRUE;
// sqlite3_stmt *statement, *addStmt;
for (NSArray *skarray in userData) {
//NSLog(@"test");
if(i == 0){
//insert all main category
for (NSDictionary *tuser in skarray) {
NSString *query = @"delete from categories";
const char *sqlStatement = [query UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSLog(@"result is here");
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {
NSLog(@"path is %s", [path UTF8String]);
sqlite3_stmt *addStmt = NULL;
const char *sqlInsert = "INSERT INTO categories (id,cat_name,order_by) VALUES(?, ?, ?)";
int result = sqlite3_prepare_v2(database,sqlInsert, -1, &addStmt, NULL);
if(result != SQLITE_OK){
NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_text(addStmt, 0, [[tuser objectForKey:@"id"] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 1, [[tuser objectForKey:@"cat_name"] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 2, [[tuser objectForKey:@"order_by"] UTF8String], -1, SQLITE_TRANSIENT);
//Execute the statement
if (result == SQLITE_OK) {
result = sqlite3_step(addStmt);
}
if (result == SQLITE_DONE || result == SQLITE_ROW) {
result = sqlite3_reset(addStmt);
NSLog(@"Inserted");
}
else{
NSLog(@"InsertFailed");
}
答案 0 :(得分:2)
有几个问题:
如果您想知道插入失败的原因,请替换
NSLog(@"InsertFailed");
使用
NSLog(@"Insert failed: %s", sqlite3_errmsg(database));
每当您收到SQL错误时,请检查错误是什么,否则您将失明。
SQLite sqlite3_bind_xxx
函数使用基于1的索引(与sqlite3_column_xxx
函数不同)。所以替换:
sqlite3_bind_text(addStmt, 0, [[tuser objectForKey:@"id"] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 1, [[tuser objectForKey:@"cat_name"] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 2, [[tuser objectForKey:@"order_by"] UTF8String], -1, SQLITE_TRANSIENT);
使用:
sqlite3_bind_text(addStmt, 1, [[tuser objectForKey:@"id"] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 2, [[tuser objectForKey:@"cat_name"] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 3, [[tuser objectForKey:@"order_by"] UTF8String], -1, SQLITE_TRANSIENT);
或者,甚至更好:
if (sqlite3_bind_text(addStmt, 1, [[tuser objectForKey:@"id"] UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind of 1 failed: %s", sqlite3_errmsg(database));
if (sqlite3_bind_text(addStmt, 2, [[tuser objectForKey:@"cat_name"] UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind of 2 failed: %s", sqlite3_errmsg(database));
if (sqlite3_bind_text(addStmt, 3, [[tuser objectForKey:@"order_by"] UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind of 3 failed: %s", sqlite3_errmsg(database));
或者,甚至更好:
if ([[tuser objectForKey:@"id"] isKindOfClass:[NSString class]])
{
if (sqlite3_bind_text(addStmt, 1, [[tuser objectForKey:@"id"] UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind of 1 failed: %s", sqlite3_errmsg(database));
}
else
{
if (sqlite3_bind_null(addStmt, 1) != SQLITE_OK)
NSLog(@"bind of null to 1 failed: %s", sqlite3_errmsg(database));
}
if ([[tuser objectForKey:@"cat_name"] isKindOfClass:[NSString class]])
{
if (sqlite3_bind_text(addStmt, 2, [[tuser objectForKey:@"cat_name"] UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind of 2 failed: %s", sqlite3_errmsg(database));
}
else
{
if (sqlite3_bind_null(addStmt, 2) != SQLITE_OK)
NSLog(@"bind of null to 2 failed: %s", sqlite3_errmsg(database));
}
if ([[tuser objectForKey:@"order_by"] isKindOfClass:[NSString class]])
{
if (sqlite3_bind_text(addStmt, 3, [[tuser objectForKey:@"order_by"] UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
NSLog(@"bind of 3 failed: %s", sqlite3_errmsg(database));
}
else
{
if (sqlite3_bind_null(addStmt, 3) != SQLITE_OK)
NSLog(@"bind of null to 3 failed: %s", sqlite3_errmsg(database));
}
将sqlite3_reset
替换为sqlite3_finalize
。 sqlite3_reset
重置语句,以便您可以绑定新值并再次执行它(这不是您需要的)。 sqlite3_finalize
释放与准备好的语句关联的内存( 你需要的内容)。
顺便说一下,无论数据库是否已存在,您的代码都会将文件从包中复制到文档中(这意味着您将丢弃下次运行应用程序时插入的任何内容)。你可能想要替换:
BOOL success = [fileMgr copyItemAtPath:bundlePath toPath:appFile error:&err];
if (!success) {
NSLog(@"Failed to create writable database file with message '%@'.", [err localizedDescription]);
}
与
if (![fileMgr fileExistsAtPath:appFile]) {
BOOL success = [fileMgr copyItemAtPath:bundlePath toPath:appFile error:&err];
if (!success) {
NSLog(@"Failed to create writable database file with message '%@'.", [err localizedDescription]);
}
}
以上所有修复了代码示例中的简单逻辑错误。你仍然有一个更深层的问题,你的JSON(我假设从your other question不变)将不符合你在这里的嵌套for
循环结构。您的三个阵列是不同类型的阵列。或者您是否因为其他问题而更改了JSON格式?
答案 1 :(得分:-1)
Well check Out here for detailed code structure.
我管理的方式是一个单独的类来管理DB
这些是您寻找的方法
-(void) checkAndCreateDatabase
{
// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;
// Create a FileManager object, we will use this to check the status
// of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:_databasePath];
// If the database already exists then return without doing anything
if(success) return;
// If not then proceed to copy the database from the application to the users filesystem
// Get the path to the database in the application package
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:_databaseName];
// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:_databasePath error:nil];
}
//-----------------------------------------------------------------------------------------------------//
#pragma mark - Helper methods
//-----------------------------------------------------------------------------------------------------//
-(BOOL)dbOpenedSuccessfully
{
if(sqlite3_open([[self dbPath] UTF8String], &_database) == SQLITE_OK)
{
return YES;
}
else
{
[[[UIAlertView alloc]initWithTitle:@"Error"
message:@"Error on opening the DB"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil]show];
return NO;
}
}
//-----------------------------------------------------------------------------------------------------//
#pragma mark - Query
//-----------------------------------------------------------------------------------------------------//
- (void) executeQuery:(NSString *)strQuery
{
char *error = NULL;
if([self dbOpenedSuccessfully])
{
NSLog(@"%@",strQuery);
sqlite3_exec(_database, [strQuery UTF8String], NULL, NULL,&error);
if (error!=nil) {
NSLog(@"%s",error);
}
sqlite3_close(_database);
}
}