0

データベースを構築していて、データベースに保存されているオブジェクトから特定のデータを取得したいと考えています。

これは私が持っているコードです:

//databaseMainViewController.m
//Create and database and save data

@implementation databaseMainViewController

@synthesize customer, code1,code2;


-(void) createTable: (NSString*)tableName
         withField1: (NSString*)field1
         withField2: (NSString*)field2
         withField3: (NSString*)field3
         withField4: (NSString*)field4; {

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

    if(sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err)!=SQLITE_OK){

        sqlite3_close(db);
        NSAssert(0, @"DCould not create table");

    }

    else {
        NSLog(@"table created");
    }
}

//file path to database
-(NSString*)filePath {
    NSArray*paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    return [[paths objectAtIndex:0]stringByAppendingPathComponent:@"bp.sql"];
}

//open database
-(void)openDB {

    if(sqlite3_open([[self filePath]UTF8String], &db) !=SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(0, @"Databese failed to open");
    }

        else {
            NSLog(@"database opemed");
        }


}

- (IBAction)save:(id)sender {

    NSString*customers = customer.text;
    NSString*codeOne = code1.text;
    NSString*codeTwo = code2.text;
    NSDate*theDate = [NSDate date];

    NSString*sql= [NSString stringWithFormat:@"INSERT INTO summary ('theDate','customer','code1','code2')VALUES ('%@','%@','%@','%@')", theDate, customers,codeOne, codeTwo];

    char*err;

    if(sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err)!=SQLITE_OK){

        sqlite3_close(db);
        NSAssert(0, @"Could not update table");

    }

    else {
        NSLog(@"table updated");
    }

    customer.text = @"";
    code1.text = @"";
    code2.text = @"";



}

- (void)viewDidLoad
{
    [self openDB];
    [self createTable:@"summary" withField1:@"theDate" withField2:@"customer" withField3:@"code1" withField4:@"code2"];
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

次に、データを取得してメインリストに入れるコードがあります

#import "databaseFlipsideViewController.h"
#import "detailViewController.h"


@interface databaseFlipsideViewController ()

@end

@implementation databaseFlipsideViewController

@synthesize entries;

//file path to database
-(NSString*)filePath {
    NSArray*paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    return [[paths objectAtIndex:0]stringByAppendingPathComponent:@"bp.sql"];
}

//open database
-(void)openDB {

    if(sqlite3_open([[self filePath]UTF8String], &db) !=SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(0, @"Databese failed to open");
    }

    else {
        NSLog(@"database opemed");
    }


}

- (void)viewDidLoad
{
    entries = [[NSMutableArray alloc]init];
    [self openDB];
    NSString*sql = [NSString stringWithFormat:@"SELECT * FROM summary"];
    sqlite3_stmt*statement;

    if (sqlite3_prepare_v2(db, [sql UTF8String], -1, &statement, nil)==SQLITE_OK) {

        while (sqlite3_step(statement)==SQLITE_ROW) {
            char*field1 = (char*)sqlite3_column_text(statement, 0);
            NSString*field1Str = [[NSString alloc]initWithUTF8String:field1];

            char*field2 = (char*)sqlite3_column_text(statement, 1);
            NSString*field2Str = [[NSString alloc]initWithUTF8String:field2];

            char*field3 = (char*)sqlite3_column_text(statement, 2);
            NSString*field3Str = [[NSString alloc]initWithUTF8String:field3];

            char*field4 = (char*)sqlite3_column_text(statement, 3);
            NSString*field4Str = [[NSString alloc]initWithUTF8String:field4];

            NSString*str = [[NSString alloc]initWithFormat:@"%@", field2Str ];
            [entries addObject:str];
        }
    }

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Actions

- (IBAction)done:(id)sender
{
    [self.delegate flipsideViewControllerDidFinish:self];
}

-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView {

    //Return the number of sections
    return 1;
}

-(NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section {
    NSString*myTitle = [[NSString alloc]initWithFormat:@"History"];
    return myTitle;
}

-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section{

    return [entries count];
    NSLog(@"%d",[entries count]);


}

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"test");

    static NSString*cellIdentifier = @"Cell";
    UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    cell.textLabel.text = [self.entries objectAtIndex:indexPath.row];
    return cell;

}

この後、リストから名前の1つをクリックすると、アプリケーションが名前の詳細を含む別のビューに移動するため、問題が発生します。しかし、すべての名前の詳細は同じです。

これは、detailViewController のコードです。

#import "detailViewController.h"

@interface detailViewController ()

@end

@implementation detailViewController

@synthesize customerLabel,code1Label,code2Label,dateLabel;

//file path to database
-(NSString*)filePath {
    NSArray*paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    return [[paths objectAtIndex:0]stringByAppendingPathComponent:@"bp.sql"];
}

//open database
-(void)openDB {

    if(sqlite3_open([[self filePath]UTF8String], &db) !=SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(0, @"Databese failed to open");
    }

    else {
        NSLog(@"database opemed");
    }


}

- (IBAction)back:(id)sender
{
    [self.delegate detailViewControllerDidFinish:self];
}

- (void)viewDidLoad
{
    [self openDB];
    NSString*sql = [NSString stringWithFormat:@"SELECT * FROM summary"];
    sqlite3_stmt*statement;


    if (sqlite3_prepare_v2(db, [sql UTF8String], -1, &statement, nil)==SQLITE_OK) {

        while (sqlite3_step(statement)==SQLITE_ROW) {


            char*field1 = (char*)sqlite3_column_text(statement, 0);
            NSString*field1Str = [[NSString alloc]initWithUTF8String:field1];

            char*field2 = (char*)sqlite3_column_text(statement, 1);
            NSString*field2Str = [[NSString alloc]initWithUTF8String:field2];

            char*field3 = (char*)sqlite3_column_text(statement, 2);
            NSString*field3Str = [[NSString alloc]initWithUTF8String:field3];

            char*field4 = (char*)sqlite3_column_text(statement, 3);
            NSString*field4Str = [[NSString alloc]initWithUTF8String:field4];



            customerLabel.text = field2Str;
            code1Label.text = field3Str;
            code2Label.text =field4Str;
            dateLabel.text = field1Str;

        }
    }

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

では、詳細画面で選択したオブジェクトの詳細を表示する最良の方法は何ですか?

4

2 に答える 2

1

この解決策は私のために働く

このコードをdatabaseFlipsideViewControllerに追加しました

//databaseFlipsideViewController.m

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"showDetail"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        detailController = segue.destinationViewController;
        detailController.customerName = [keys objectAtIndex:indexPath.row];
        NSLog(@"%@", detailController.customerName);
  }
}

そして私のdetailViewControllerコードはこれです:

@implementation detailViewController

@synthesize customerLabel,code1Label,code2Label,dateLabel,customerName,code1Name;

//file path to database
-(NSString*)filePath {
    NSArray*paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    return [[paths objectAtIndex:0]stringByAppendingPathComponent:@"bp.sql"];
}

//open database
-(void)openDB {

    if(sqlite3_open([[self filePath]UTF8String], &db) !=SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(0, @"Databese failed to open");
    }

    else {
        NSLog(@"database opemed");
    }


}

- (IBAction)back:(id)sender
{
    [self.delegate detailViewControllerDidFinish:self];
}

- (void)viewDidLoad
{

    [self openDB];
    NSString*sql = [NSString stringWithFormat:@"SELECT theDate, customer,code1,code2 FROM summary WHERE key=\"%@\"", customerName];
     const char *query_stmt = [sql UTF8String];
    sqlite3_stmt*statement;

    if (sqlite3_prepare_v2(db, query_stmt, -1, &statement, nil)==SQLITE_OK) {

        if (sqlite3_step(statement)==SQLITE_ROW) {

            NSString *date = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
            dateLabel.text = date;

            NSString *customer = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
            customerLabel.text = customer;

            NSString *code1 = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
            code1Label.text = code1;

            NSString *code2 = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement,3)];
            code2Label.text = code2;

        }
        sqlite3_finalize(statement);

            [super viewDidLoad];
        }
    sqlite3_close(db);
    }
于 2013-02-06T15:32:46.463 に答える
0

in - (void)viewDidLoadfrom detailViewControlleryour select queryは user/summary を指定していないため、それではなく、すべてを選択します

while ループでは、データベースの各行のすべてのラベル プロパティを上書きします。そのため、結果は常に同じように見え、データベースからの最後の結果が表示されます..

答えは、tableView のdidSelectRowAtIndexPath関数を実装し、ユーザーの ID を detailView コントローラに渡すことです。次に、より具体的なクエリを使用して正しいエントリを取得します。

@"SELECT * FROM x WHERE id = '%@'", _id;

しかし、実際には基本的なレッスンのSQLが必要だと思います..

プロのヒント: Core Data の使用を検討してください。Core Data が機能やパフォーマンスを制限している場合、iPhone で SQLite だけが本当に必要です..

于 2013-02-05T10:10:06.597 に答える