2014-12-15 1 views
1

내가 sqlite database iOS app tutorial에서 코드를 사용하고 있지만, 기록 삽입 할 때 SQL 오류를주고있다 : ViewController.h 파일이그런 테이블에 없습니다 .. 쿼리를 실행할 수 없습니다 ... 엑스 코드 SQLite는

2014-12-15 12:08:08.458 SQLite3DBSample[2677:60b] no such table: peopleInfo 
2014-12-15 12:08:18.703 SQLite3DBSample[2677:60b] no such table: peopleInfo 
2014-12-15 12:08:18.704 SQLite3DBSample[2677:60b] Could not execute the query. 

코드에를 : EditInfoViewController.h에서

#import "ViewController.h" 
#import "DBManager.h" 


@interface ViewController() 

@property (nonatomic, strong) DBManager *dbManager; 

@property (nonatomic, strong) NSArray *arrPeopleInfo; 

@property (nonatomic) int recordIDToEdit; 


-(void)loadData; 

@end 


@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

    // Make self the delegate and datasource of the table view. 
    self.tblPeople.delegate = self; 
    self.tblPeople.dataSource = self; 

    // Initialize the dbManager property. 
    self.dbManager = [[DBManager alloc] initWithDatabaseFilename:@"sampledb.sql"]; 

    // Load the data. 
    [self loadData]; 
} 

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


-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ 
    EditInfoViewController *editInfoViewController = [segue destinationViewController]; 
    editInfoViewController.delegate = self; 
    editInfoViewController.recordIDToEdit = self.recordIDToEdit; 
} 


#pragma mark - IBAction method implementation 

- (IBAction)addNewRecord:(id)sender { 
    // Before performing the segue, set the -1 value to the recordIDToEdit. That way we'll indicate that we want to add a new record and not to edit an existing one. 
    self.recordIDToEdit = -1; 

    // Perform the segue. 
    [self performSegueWithIdentifier:@"idSegueEditInfo" sender:self]; 
} 


#pragma mark - Private method implementation 

-(void)loadData{ 
    // Form the query. 
    NSString *query = @"select * from peopleInfo"; 

    // Get the results. 
    if (self.arrPeopleInfo != nil) { 
     self.arrPeopleInfo = nil; 
    } 
    self.arrPeopleInfo = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]]; 

    // Reload the table view. 
    [self.tblPeople reloadData]; 
} 


#pragma mark - UITableView method implementation 

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ 
    return 1; 
} 


-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 
    return self.arrPeopleInfo.count; 
} 


-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    // Dequeue the cell. 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"idCellRecord" forIndexPath:indexPath]; 

    NSInteger indexOfFirstname = [self.dbManager.arrColumnNames indexOfObject:@"firstname"]; 
    NSInteger indexOfLastname = [self.dbManager.arrColumnNames indexOfObject:@"lastname"]; 
    NSInteger indexOfAge = [self.dbManager.arrColumnNames indexOfObject:@"age"]; 

    // Set the loaded data to the appropriate cell labels. 
    cell.textLabel.text = [NSString stringWithFormat:@"%@ %@", [[self.arrPeopleInfo objectAtIndex:indexPath.row] objectAtIndex:indexOfFirstname], [[self.arrPeopleInfo objectAtIndex:indexPath.row] objectAtIndex:indexOfLastname]]; 

    cell.detailTextLabel.text = [NSString stringWithFormat:@"Age: %@", [[self.arrPeopleInfo objectAtIndex:indexPath.row] objectAtIndex:indexOfAge]]; 

    return cell; 
} 


-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    return 60.0; 
} 


-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{ 
    // Get the record ID of the selected name and set it to the recordIDToEdit property. 
    self.recordIDToEdit = [[[self.arrPeopleInfo objectAtIndex:indexPath.row] objectAtIndex:0] intValue]; 

    // Perform the segue. 
    [self performSegueWithIdentifier:@"idSegueEditInfo" sender:self]; 
} 


-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ 

    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     // Delete the selected record. 
     // Find the record ID. 
     int recordIDToDelete = [[[self.arrPeopleInfo objectAtIndex:indexPath.row] objectAtIndex:0] intValue]; 

     // Prepare the query. 
     NSString *query = [NSString stringWithFormat:@"delete from peopleInfo where peopleInfoID=%d", recordIDToDelete]; 

     // Execute the query. 
     [self.dbManager executeQuery:query]; 

     // Reload the table view. 
     [self loadData]; 
    } 
} 


#pragma mark - EditInfoViewControllerDelegate method implementation 

-(void)editingInfoWasFinished{ 
    // Reload the data. 
    [self loadData]; 
} 


@end 

코드는 다음과 같습니다 나는 데이터베이스를 제거하더라도

#import "EditInfoViewController.h" 
#import "DBManager.h" 


@interface EditInfoViewController() 

@property (nonatomic, strong) DBManager *dbManager; 

-(void)loadInfoToEdit; 

@end 


@implementation EditInfoViewController 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 

    // Make self the delegate of the textfields. 
    self.txtFirstname.delegate = self; 
    self.txtLastname.delegate = self; 
    self.txtAge.delegate = self; 

    // Set the navigation bar tint color. 
    self.navigationController.navigationBar.tintColor = self.navigationItem.rightBarButtonItem.tintColor; 

    // Initialize the dbManager object. 
    self.dbManager = [[DBManager alloc] initWithDatabaseFilename:@"sampledb.sql"]; 

    // Check if should load specific record for editing. 
    if (self.recordIDToEdit != -1) { 
     // Load the record with the specific ID from the database. 
     [self loadInfoToEdit]; 
    } 
} 

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

/* 
#pragma mark - Navigation 

// In a storyboard-based application, you will often want to do a little preparation before navigation 
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    // Get the new view controller using [segue destinationViewController]. 
    // Pass the selected object to the new view controller. 
} 
*/ 


#pragma mark - UITextFieldDelegate method implementation 

-(BOOL)textFieldShouldReturn:(UITextField *)textField{ 
    [textField resignFirstResponder]; 
    return YES; 
} 


#pragma mark - IBAction method implementation 

- (IBAction)saveInfo:(id)sender { 
    // Prepare the query string. 
    // If the recordIDToEdit property has value other than -1, then create an update query. Otherwise create an insert query. 
    NSString *query; 
    if (self.recordIDToEdit == -1) { 
     query = [NSString stringWithFormat:@"insert into peopleInfo values(null, '%@', '%@', %d)", self.txtFirstname.text, self.txtLastname.text, [self.txtAge.text intValue]]; 
    } 
    else{ 
     query = [NSString stringWithFormat:@"update peopleInfo set firstname='%@', lastname='%@', age=%d where peopleInfoID=%d", self.txtFirstname.text, self.txtLastname.text, self.txtAge.text.intValue, self.recordIDToEdit]; 
    } 


    // Execute the query. 
    [self.dbManager executeQuery:query]; 

    // If the query was successfully executed then pop the view controller. 
    if (self.dbManager.affectedRows != 0) { 
     NSLog(@"Query was executed successfully. Affected rows = %d", self.dbManager.affectedRows); 

     // Inform the delegate that the editing was finished. 
     [self.delegate editingInfoWasFinished]; 

     // Pop the view controller. 
     [self.navigationController popViewControllerAnimated:YES]; 
    } 
    else{ 
     NSLog(@"Could not execute the query."); 
    } 
} 


#pragma mark - Private method implementation 

-(void)loadInfoToEdit{ 
    // Create the query. 
    NSString *query = [NSString stringWithFormat:@"select * from peopleInfo where peopleInfoID=%d", self.recordIDToEdit]; 

    // Load the relevant data. 
    NSArray *results = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]]; 

    // Set the loaded data to the textfields. 
    self.txtFirstname.text = [[results objectAtIndex:0] objectAtIndex:[self.dbManager.arrColumnNames indexOfObject:@"firstname"]]; 
    self.txtLastname.text = [[results objectAtIndex:0] objectAtIndex:[self.dbManager.arrColumnNames indexOfObject:@"lastname"]]; 
    self.txtAge.text = [[results objectAtIndex:0] objectAtIndex:[self.dbManager.arrColumnNames indexOfObject:@"age"]]; 
} 


@end 

파일을 만들고 동일한 오류를주는 새 데이터베이스를 만듭니다. 이 오류를 수정하는 방법은 무엇입니까? 어떤 제안이라도 대단히 감사합니다.

+0

->http://sqlitebrowser.org/

자세한 내용은이 링크를 참조하시기 바랍니다? –

+0

db 파일은 데이터베이스 파일 –

+0

을 의미합니다. 예, 데이터베이스 파일에 있습니다. –

답변

4

실제로 쿼리는 아무 문제없이 실행됩니다. 그래서,

if (sqlite3_step(compiledStatement) == SQLITE_DONE) 
{ 
    ... 
} 

SQLITE_DONE 값 (101)으로 정의 된 매크로, 당신은 BOOL로 그 비교하려고 : 해당

BOOL executeQueryResults = sqlite3_step(compiledStatement); 
if (executeQueryResults == SQLITE_DONE) 
{ 
    ... 
} 

변경 : 귀하의 메시지가 다음 코드를 잘못 제공 조건이 매번 실패합니다.

+0

여전히 작동하지 않습니다 ... 동일한 오류가 발생했습니다 ...이 프로젝트의 이전 문제점은 다음과 같습니다. http://stackoverflow.com/questions/27456053/db-error-database-disk-image-is-malformed –

+1

@frincit 방금 코드를 다운로드하고 보관 용 상자에 넣고 변경했습니다. 그것은 나를 위해 완벽하게 작동합니다. –

1

이 문제는 시뮬레이터의 "다시 설정하라는 내용 및 설정"에 의해 해결 될 수

-(void)viewDidAppear:(BOOL)animated{ 
[super viewDidAppear:YES]; 
[self loadData]; } 
0

처럼 viewdidAppear에 테이블을로드하지만 코드가 정확하고 테이블이 정말 처음 데이터베이스에 존재하는지 확인하십시오. "sqlite 브라우저"를 사용하여 데이터베이스와 테이블을 확인할 수 있습니다. 이 링크에서 "sqlite가 브라우저"를 다운로드 할 수 있습니다 - 모든 테이블이 DB 파일에 그 이름이 있습니까>sqlite prepare statement error - no such table

enter image description here

관련 문제