我无法读取预先存在的sqlite数据库

时间:2013-03-28 09:39:11

标签: iphone ios objective-c sqlite

我已将预先填充的sqlite数据库从bundle复制到库路径。现在,当我尝试执行查询时,它不会读取数据库。

复制数据库的代码:

-(void)createDatabase
{
    NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
    NSString *targetPath = [libraryPath stringByAppendingPathComponent:@"gre.db"];


    if (![[NSFileManager defaultManager] fileExistsAtPath:targetPath]) {
        // database doesn't exist in your library path... copy it from the bundle
        NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"gre.db"];
        NSError *error = nil;

        if (![[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:targetPath error:&error]) {
            NSLog(@"Error: %@", error);
        }
    }
}

我从我的applicationDidFinishLaunchLaunchingWithOptions中调用它并复制数据库

这是我查询数据库的查询:

-(void)readDatabase
{
    wordlist = [[NSMutableArray alloc] init];
    NSString *query =[NSString stringWithFormat:@"SELECT word FROM words WHERE word LIKE '%@%%'",selectedWord]; 
    sqlite3_stmt *statement;
    if (sqlite3_prepare_v2(database, [query UTF8String],-1, &statement, nil) == SQLITE_OK)
    {
        while (sqlite3_step(statement) == SQLITE_ROW)
        {
            char *id1 = (char *)sqlite3_column_text(statement, 0);
            [wordlist addObject:[NSString stringWithFormat:@"%s",id1]];
        }
    }
    sqlite3_finalize(statement);

    NSLog(@"%@",wordlist);

}

现在控件没有进入*while (sqlite3_step(statement) == SQLITE_ROW)*循环 因此不显示数据。

4 个答案:

答案 0 :(得分:0)

使用此代码并检查数据库是否已连接并正确打开,然后再从中获取数据。希望这会有所帮助。

-(void)readDatabase
    {
        // Set path 
        NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);//(customize the path based on ur database location)

        NSString *docsDir = [dirPaths objectAtIndex:0];

        NSString *databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"database.db"]];
     const char *dbpath = [databasePath UTF8String]; 


         //Checking connection 
         if (sqlite3_open(dbpath, &SQLitedatabase) == SQLITE_OK)
               {
                 wordlist = [[NSMutableArray alloc] init];
                 NSString *query =[NSString stringWithFormat:@"SELECT word FROM words WHERE word LIKE '%@%%'",selectedWord];
                 sqlite3_stmt *statement;
                 if (sqlite3_prepare_v2(database, [query UTF8String],-1, &statement, nil) == SQLITE_OK)
                 {
                 while (sqlite3_step(statement) == SQLITE_ROW)
                 {
                 char *id1 = (char *)sqlite3_column_text(statement, 0);
                 [wordlist addObject:[NSString stringWithFormat:@"%s",id1]];
                 }
                 }
                 sqlite3_finalize(statement);

                 }
              }  
    }

并确保DB的初始化也像这样......

#import <sqlite3.h>

NSString *databasePath;

sqlite3 *SQLiteDataBaseDB;

@implementation DatabaseManager
+(void)initializeDb 
{
    NSString *docsDir;
    NSArray *dirPaths;

    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    docsDir = [dirPaths objectAtIndex:0];

    databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"database.db"]];

    NSFileManager *filemgr = [NSFileManager defaultManager];

    if ([filemgr fileExistsAtPath: databasePath ] == NO)
    {
        const char *dbpath = [databasePath UTF8String];

        if (sqlite3_open(dbpath, &SQLiteDataBaseDB) == SQLITE_OK)
        {
            char *errMsg;
            //SELECT name FROM sqlite_master WHERE name=USER_VIDEO_INFO

            const char *sql_stmt = "CREATE TABLE IF NOT EXISTS USER_VIDEO_INFO (userIdentifier TEXT, managerName TEXT, videoPath TEXT, videoName TEXT, shotDate TEXT, session TEXT, videoCategory TEXT)";

            if (sqlite3_exec(SQLiteDataBaseDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
            {
                NSLog(@"Failed to create table");
            }

            sqlite3_close(SQLiteDataBaseDB);

        } 
        else
        {
            NSLog(@"Failed to open/create database");
        }

           }

}

并检查物理上是否创建了DB ...

enter image description here

答案 1 :(得分:0)

如果您的数据库文件位于资源目​​录中,请尝试以下代码:

-(NSString*)databasePath
{
   NSString *dbPath = [[NSBundle mainBundle] pathForResource:"gre" forType:"db"];
   return dbPath;
}

实际上你正在为你的数据库找错路径。

答案 2 :(得分:0)

您可以测试以下代码。它对我来说很好。

if (userDB == NULL) {
        sqlite3 *newDBconnection;

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *path = [documentsDirectory stringByAppendingPathComponent:@"gre.sqlite"];

        // 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:path];

        // If the database already exists then dont do anything
        if(!success)
        {
            NSLog(@"not success");
            // 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:@"pero1.sqlite"];

            // Copy the database from the package to the users filesystem
            [fileManager copyItemAtPath:databasePathFromApp toPath:path error:nil];

        }
        NSLog(@"success");

        if (sqlite3_open([path UTF8String], &newDBconnection) == SQLITE_OK) {   
            //NSLog(@"Database Successfully Opened :)");
            userDB = newDBconnection;
        } else {
            NSLog(@"Error in opening database :(");
            userDB = NULL;
    return;
        }
    }
    wordlist = [[NSMutableArray alloc] init];

NSString *query = [NSString stringWithFormat:@"SELECT word FROM words WHERE word LIKE '%@%%'",selectedWord];
        NSLog(@"query: %@",query);

        const char *sqlStatement = [query UTF8String];
        sqlite3_stmt *compiledStatement;
    NSString *listFromDB = @"";
        if(sqlite3_prepare_v2(userDB, 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
                char *id1 = (char *)sqlite3_column_text(statement, 0);
            [wordlist addObject:[NSString stringWithFormat:@"%s",id1]];

                }
        }
        // Release the compiled statement from memory
        sqlite3_finalize(compiledStatement);

答案 3 :(得分:0)

Ganapathy你的代码很棒!但不是在每个选择查询之前打开数据库,

我在我的代码中尝试了这个,它就像一个魅力!

-(void)createDatabase
{
    NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
    NSString *targetPath = [libraryPath stringByAppendingPathComponent:@"gre.db"];


    if (![[NSFileManager defaultManager] fileExistsAtPath:targetPath]) {
        // database doesn't exist in your library path... copy it from the bundle
        NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"gre.db"];
        NSError *error = nil;

        if (![[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:targetPath error:&error]) {
            NSLog(@"Error: %@", error);
        }
    }

    //Open Database
    if (sqlite3_open([targetPath UTF8String], &database) != SQLITE_OK)
    {
        sqlite3_close(database);
        NSLog(@"Failed to open db.");
    }

}