6

実行時に Objective-C を使用して SQLite3 データベース ファイルを作成しようとしています。「tblStore」というテーブルを作成しようとしています。フィールド名を「strStoreNumber」および「strStoreReg」と呼びたいです。私は iOS と SQLite が初めてなので、これを実行するための構文を見つけるのに苦労しています。テーブルを作成することに加えて、作成したテーブルをアプリバンドルに常駐させず、電話のどこかに常駐/保存するようにします。テーブルは読み取り/書き込み可能である必要があります。「ユーザーサンドボックス」と「ドキュメントディレクトリ」について読んだことがあります。2つの違いを理解しているかどうかはわかりません。理想的には、私のアプリはボタンを使用してテキスト フィールドから入力を取得します。テキストフィールドからの入力が文字列に入れられた後、

要約: 1. フィールド「strStoreNumber」と「strStoreReg」を持つ「tblStore」という名前のテーブルを作成するための Obj-C/SQLite の構文は何ですか? 2. db ファイルはどこにありますか? tblStore db ファイルを読み書きする必要があります。3. 「ユーザー サンドボックス」と「ドキュメント ディレクトリ」の違いは何ですか?

これは私が現在持っているものです:

-(IBAction)setInput:(id)sender
{
    NSString *strStoreNumber;
    NSString *strRegNumber;
    NSString *tableName = @"tblStore";
    NSString *dbStrStore = @"strStore";
    NSString *dbStrReg = @"strReg";


    strStoreNumber = StoreNumber.text;
    strRegNumber = RegNumber.text;

    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* documentsDirectory = [paths lastObject];
    NSString* databasePath = [documentsDirectory stringByAppendingPathComponent:@"tblStore.sqlite"];
//  NSString* databasePath = [[NSBundle mainBundle] pathForResource:@"tblStore" ofType:@"sqlite"];

    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) 
    {
        NSLog(@"Opened sqlite database at %@", databasePath);

        char *err; 
        NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS '%@' ('%@' TEXT PRIMARY KEY, '%@' TEXT);", tableName, dbStrStore, dbStrReg];
        if (sqlite3_exec(database, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK) 
        { 
            sqlite3_close(database);
            NSAssert(0, @"Table failed to create.");
        }
        //...stuff
    } 
    else 
    {
        NSLog(@"Failed to open database at %@ with error %s", databasePath, sqlite3_errmsg(database));
        sqlite3_close (database);
    }

    NSString *querystring;

    // create your statement
    querystring = [NSString stringWithFormat:@"SELECT strStore, strReg FROM tblStore WHERE strStore = %@ AND strReg = %@;", strStoreNumber, strRegNumber];  

    const char *sql = [querystring UTF8String];

    NSString *szStore = nil;
    NSString *szReg = nil;

    sqlite3_stmt *statement = nil;
    if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL)!=SQLITE_OK) //queryString = Statement
    {
        NSLog(@"sql problem occured with: %s", sql);
        NSLog(@"%s", sqlite3_errmsg(database));
    }
    else
    {
        // you could handle multiple rows here
        while (sqlite3_step(statement) == SQLITE_ROW) 
        {            
            szStore = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 0)];
            szReg = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 1)];
        }        
    }

    sqlite3_finalize(statement);

    lblStoreNumber.text = szStore;
    lblRegNumber.text = szReg;   
} 

アプリを実行すると、次のエラーが発生します。

2012-05-10 14:58:38.169 CCoDBTry[355:f803] Opened sqlite database at /Users/Matt****/Library/Application Support/iPhone Simulator/5.1/Applications/5DB7A218-A0F6-   485F-B366-91FD2F9BC062/Documents/tblStore.sqlite
2012-05-10 14:58:38.307 CCoDBTry[355:f803] sql problem occured with: SELECT strStore, strReg FROM tblStore WHERE strStore = 8053 AND strReg = 4;
2012-05-10 14:58:38.308 CCoDBTry[355:f803] no such column: strStore

私は非常に新しく、試したことのいくつかを達成できなかったので、このことのいくつかを説明するために時間を割いてくれる人に感謝します. 助けてくれてどうもありがとう!

4

7 に答える 7

12

// DB を作成

-(NSString *) filePath
{
 NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *documentDirectory=[paths objectAtIndex:0];
 return [documentDirectory stringByAppendingPathComponent:@"LoginDatabase.sql"];
}

// DBを開く

-(void)openDB
{
 if(sqlite3_open([[self filePath]UTF8String], &db) !=SQLITE_OK)
 {
   sqlite3_close(db);
   NSAssert(0, @"Database failed to Open");
 }
}

// テーブルを作成

-(void) createTableNamed:(NSString*)tableName withField1:(NSString*) field1 withField2:(NSString*) field2

{
   char *err;
   NSString *sql=[NSString stringWithFormat:@" CREATE TABLE IF NOT EXISTS '%@'('%@' TEXT PRIMARY KEY,'%@' TEXT);",tableName,field1,field2];

   if(sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) !=SQLITE_OK)
   {
    sqlite3_close(db);
    NSAssert(0, @"Table failed to create");
   }
}

// レコードの挿入

-(void)insertrecordIntoTable:(NSString*) tableName withField1:(NSString*) field1 field1Value:(NSString*)field1Vaue andField2:(NSString*)field2 field2Value:(NSString*)field2Value
{

  NSString *sqlStr=[NSString stringWithFormat:@"INSERT INTO '%@'('%@','%@')VALUES(?,?)",tableName,field1,field2];
 const char *sql=[sqlStr UTF8String];

 sqlite3_stmt *statement1;

 if(sqlite3_prepare_v2(db, sql, -1, &statement1, nil)==SQLITE_OK)
 {
  sqlite3_bind_text(statement1, 1, [field1Vaue UTF8String], -1, nil);
  sqlite3_bind_text(statement1, 2, [field2Value UTF8String], -1, nil);
 }
 if(sqlite3_step(statement1) !=SQLITE_DONE)
    NSAssert(0, @"Error upadating table");
 sqlite3_finalize(statement1);
}

// テーブルからデータを取得

-(void)getAllRowsFromTableNamed:(NSString *)tableName
{
  NSString *field1Str,*field2Str;

  NSString *qsql=[NSString stringWithFormat:@"SELECT * FROM %@",tableName];
  sqlite3_stmt *statement;
  if(sqlite3_prepare_v2(db, [qsql UTF8String], -1, &statement, nil)==SQLITE_OK)
  {
   while(sqlite3_step(statement) ==SQLITE_ROW)
   {
     char *field1=(char *) sqlite3_column_text(statement, 0);
     char *field2=(char *) sqlite3_column_text(statement, 1);

     field1Str=[[NSString alloc]initWithUTF8String:field1];
     field2Str=[[NSString alloc] initWithUTF8String:field2];

     NSString *str=[NSString stringWithFormat:@"%@ - %@",field1Str,field2Str];
     NSLog(@"%@",str);
   }
}

}

viewDidLoad でメソッドを呼び出します

- (void)viewDidLoad
{

  [self openDB];
  [self createTableNamed:@"Login" withField1:@"USERNAME" withField2:@"PASSWORD"];
  [self insertrecordIntoTable:@"Login" withField1:@"USERNAME" field1Value:username andField2:@"PASSWORD" field2Value:password];

}

ユーザー名とパスワードは NSString 値です。

于 2012-08-03T12:04:27.693 に答える
2

自分が何をしているのかわからない場合、sqliteは苦痛です。sqlite c 関数にも問題がありましたが、sqlite ラッパーを使用することにしました。

FMDBBWDBは、目的 c のための優れた使いやすい sqlite ラッパーです。それらのいずれかを使用することをお勧めします。

BWDB は lynda.com のチュートリアル (これ) にあることに注意してください。Web で見つからない場合は、コメントを残してください。どこかにアップロードします。

編集:アプリで何かを書くことができる唯一の場所は、ドキュメントディレクトリです...だから..それは簡単な言葉です...データベースがドキュメントディレクトリにない場合..読み取り専用です..また..いつあなたはあなたのdbに読み書きします..OSはドキュメントディレクトリにdbをコピーします..そこですべての読み書きを行うので、アプリバンドルにdbを含めることができますが、それを編集することはできません...あなたは2デシベルで終わるでしょう.私も同じ問題を抱えていました..アプリを更新したときに2デシベルをマージして修正しました

edit2:BWDBの最終プロジェクトをアップロードしました(そこにラッパーがあり、プロジェクトがどのように機能するかを確認できます)

于 2012-05-10T19:30:10.900 に答える
2

次のコードを使用して、Documents フォルダーに作成されたデータベースを取得できます。ドキュメント フォルダにパスを渡すだけで、関数は必要に応じて指定されたパスのドキュメント フォルダに sqlite データベースをコピーします。その後、このパスを使用して、データベース テーブルを作成およびクエリできます。

+ (NSString*) createDatabaseIfRequiredAtPath:(NSString*)databasePath {

    if (databasePath == nil)
       return nil;


   NSString *path = [NSString stringWithFormat:@"%@/%@", databasePath, kMainDBName];
   NSFileManager *fileManager = [NSFileManager defaultManager];
   NSError *error = nil;

   if ([fileManager fileExistsAtPath:path] == NO) 
   {
    // The writable database does not exist, so copy the default to the appropriate location.
      NSString *defaultDBPath = [[NSBundle mainBundle] pathForResource:kMainDBName
                                                              ofType:nil];
      BOOL success = [fileManager copyItemAtPath:defaultDBPath 
                                       toPath:path
                                        error:&error];
      if (!success)
      {
        NSCAssert1(0, @"Failed to create writable database file with message '%@'.", [  error localizedDescription]);
        return nil;
    }
}

return path;
于 2012-05-10T19:50:08.533 に答える
0

ターミナルを開いて /Users/Matt* * /Library/Application Support/iPhone Simulator/5.1/Applications/5DB7A218-A0F6-485F-B366-91FD2F9BC062/Documents/ に移動できます。

次に、sqlite3 tblStore.sqlite

.schema tblStore を使用すると、テーブル スキーマが表示され、正しく構築されたかどうかを確認できます。

データベースは、書き込みアクセスのためにドキュメント ディレクトリにある必要があります。データベースが読み取り専用である場合、アプリケーション バンドルに書き込まれることはありません。これを実現する 1 つの方法は、database.sqlite ファイルを作成してバンドルに追加し、起動時にドキュメント ディレクトリにコピーすることです (まだ存在しない場合)。

于 2012-05-10T19:34:02.017 に答える
0

CoreData を使用するのではなく、SQLLite を直接使用したい特定の理由はありますか? CoreData は SQLLite データベースを使用しますが、それ自体が高レベルの API であり、特にテーブル ビューなどでは、Xcode で既に設定されている多くの機能とテンプレート メソッドを利用できます。データ モデルの定義は簡単で、大量のボイラープレート コードが得られますが、すべて最適化されています。

http://www.raywenderlich.com/934/core-data-on-ios-5-tutorial-getting-started

CoreData は、学習曲線が急勾配であると説明されることがあります。同意しません。アプリで SQL を自分で作成することを検討している場合、CoreData で問題が発生することはありません。

「サンドボックス」という用語は、アプリケーションが読み取り/書き込みアクセスできるデバイスのファイルシステムの部分を表す抽象的な用語です。"Documents" ディレクトリは、アプリケーションのサンドボックス内の特定のディレクトリです。サンドボックスにはドキュメント ディレクトリ以外のファイルもありますが、iOS のファイル システムにデータを保存するほとんどのアプリケーションは、ドキュメント ディレクトリにデータを保存します。

于 2012-05-10T19:34:23.053 に答える
0

テーブルの挿入を忘れたのかもしれません。データベースとテーブルを作成しましたが、空のテーブルです。空のテーブルからレコードを読み取ろうとしています。

于 2013-06-06T19:38:13.243 に答える