2

我为一个项目使用了一个 sqlite 数据库。我可以执行 SELECT 之类的查询,但无法执行 INSERT!在模拟器上,INSERT 工作正常。一旦我在我的 iPod 上编译,就会出现此错误消息:“尝试写入只读数据库”

以为是对的文件我做了一个:chmod 777 mydatabase.sqlite 但那不改变!

我也尝试过,因为我在其他网站上阅读过并复制文件以使用他的副本来解决问题,但无济于事。

你有解决办法吗?亲切地。

PS:这是我的代码:

for(NSDictionary *q in quotes) {
    sqlite3_stmt    *statement;
    sqlite3 *contactDB;
    const char *dbpath = [dbPath UTF8String];

    if (sqlite3_open_v2(dbpath, &contactDB, SQLITE_OPEN_READWRITE, NULL) == SQLITE_OK)
    {
        NSInteger identifiant = [[q objectForKey:@"id"] integerValue];
        NSString *texte = [q objectForKey:@"texte_english"];
        NSString *auteur = [q objectForKey:@"auteur"];
        NSString *date = [q objectForKey:@"date"];
        NSInteger auteurId = [[q objectForKey:@"auteur_id"] integerValue];
        NSInteger nbComments = [[q objectForKey:@"nb_comments"] integerValue];

        NSString *insertSQL = 
                [NSString stringWithFormat:@"INSERT INTO quotes (id, texte_english, auteur, date, auteur_id, nb_comments) VALUES (%d, \"%@\", \"%@\", \"%@\", \"%d\", \"%d\")", 
                                          identifiant, 
                                          texte, 
                                          auteur, 
                                          date, 
                                          auteurId, 
                                          nbComments];

        const char *insert_stmt = [insertSQL UTF8String];
        sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);

        if (sqlite3_step(statement) != SQLITE_DONE)
        {
            NSLog(@"ERREUR1: %s",sqlite3_errmsg(contactDB));
        }
        sqlite3_finalize(statement);
        sqlite3_close(contactDB);
    }
}
4

5 回答 5

7

您需要做的就是更改您在手机中保存 SQLite 文件的根目录,该文件目前是只读的。进行这些更改:

将这些代码添加到您的AppDelegate

.h 文件:

@property (nonatomic,retain) NSFileManager *fileMgr;
@property (nonatomic,retain) NSString *homeDir;
@property (nonatomic,retain) NSString *title;

.m 文件:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [self checkAndCreateDatabase];
    return YES;
}

-(NSString *)GetDocumentDirectory{
    fileMgr = [NSFileManager defaultManager];
    homeDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    return homeDir;
}

    -(void) checkAndCreateDatabase{
    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *databasePath = [self.GetDocumentDirectory stringByAppendingPathComponent:@"YOUR DATABASE NAME.sqlite"];
    success = [fileManager fileExistsAtPath:databasePath];
    if(success) {
        NSLog(@"working");
        return;}
    else{
        NSLog(@"notworking");
    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"YOUR DATABASE NAME.sqlite"];
    [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
    }
}

同样在你SQLite class添加这些行:

.h 文件:

@property (nonatomic,retain) NSFileManager *fileMgr;
@property (nonatomic,retain) NSString *homeDir;

.m 文件:

-(NSString *)GetDocumentDirectory{
    fileMgr = [NSFileManager defaultManager];
    homeDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    return homeDir;
}

并在 INSERT 和 SELECT 中进行这些更改:

NSString *dbPath = [self.GetDocumentDirectory stringByAppendingPathComponent:@"YOUR DATABASE NAME.sqlite"];
    const char *dbpath = [dbPath UTF8String];

希望能帮助到你 :)

于 2012-10-28T12:49:19.463 回答
1
-(void)createEditablecopyofDatabaseifneeded
{
    BOOL success;
    NSError *error;
    NSFileManager *filemanagr = [NSFileManager defaultManager];

    NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *dbPath = [path objectAtIndex:0];
    NSString *finalDBPath = [dbPath stringByAppendingPathComponent:mDataBaseName];
    self.mDataBasePath=finalDBPath;
    success = [filemanagr fileExistsAtPath:finalDBPath];
    if (success) {

    }
    else
    {
        NSString *writableDBPath = [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:mDataBaseName];
        success = [filemanagr copyItemAtPath:writableDBPath toPath:finalDBPath error:&error];
        self.mDataBasePath=writableDBPath;
    }
    if (!success) {

    }
}

在文档目录中创建数据库之前检查这一点希望这会对您有所帮助

于 2013-12-11T09:44:11.617 回答
0

我找到了解决方案:

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

所以,我有这个错误:“没有这样的表:引号”有什么想法吗?

我希望它会有用!

于 2012-08-17T15:46:44.753 回答
0

万一其他人看到这个......升级到 Xcode 5.2 后,我开始在我的一台设备(iPhone 4s/iOS7)上收到此错误。这在我的 iPhone 5 (iOS 6) 上没有发生。从商店获取元数据时发生:

NSDictionary *storeMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:storeURL error:&error];

删除我的应用程序并重新安装它可以解决问题。

于 2013-12-12T17:26:58.363 回答
0

使用 GRDB 的 Swift 3

var dbQueue: DatabaseQueue!

func setUpDatabasePath()
{
    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! as NSString
    let databasePath = documentsPath.appendingPathComponent("your_database.sqlite")
    print("DATABASE PATH !!!!")
    print(databasePath)
    let fileManager:FileManager = FileManager.default
    var success = fileManager.fileExists(atPath: databasePath)
    if (success)
    {
        dbQueue = try! DatabaseQueue(path: databasePath)
        print("writing to documents directory")
        print(databasePath)
        //break
        return
    }
    if (!success)
    {
        let bundlePath = Bundle.main.path(forResource: "your_database", ofType: "sqlite")
        success = fileManager.fileExists(atPath: bundlePath!)
        print("writing from app bundle")
        if (success)
        {
            try! fileManager.copyItem(atPath: bundlePath!, toPath: databasePath)
            dbQueue = try! DatabaseQueue(path: databasePath)
        }
        else
        {
            print("Could not find database")
        }
        return
    }
}
于 2017-07-27T16:34:00.680 回答