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) {

    }
}

ドキュメント ディレクトリに DB を作成する前に、これを確認してください。

于 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にアップグレードした後、デバイスの1つ(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 に答える