[英]Retrieve data from sqLite database ios iphone application
我正在建立一個數據庫,我想從數據庫中保存的對象中檢索特定數據。
這是我的代碼:
//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;
}
在此之后,我遇到了一個問題,因為當我單擊列表中的一個名稱時,應用程序將轉到另一個包含該名稱詳細信息的視圖。 但是每個名字的細節都是一樣的。
這是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.
}
那么在詳細信息屏幕中顯示所選對象的詳細信息的最佳方法是什么
這個解決方案對我有用
我已將此代碼添加到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);
}
因為來自detailViewController
- (void)viewDidLoad
,您的選擇查詢未指定用戶/摘要 ,而是指定了 所有內容 。
在while循環中,您將覆蓋數據庫中每一行的所有標簽屬性。 因此結果將始終看起來相同,顯示數據庫的最后結果。
答案是實現tableView的didSelectRowAtIndexPath函數,並將用戶的ID傳遞給detailView控制器,然后在其中使用更具體的查詢來獲取正確的條目,即:
@“ SELECT * FROM x WHERE id ='%@'”,_id;
Protip:考慮使用Core Data,這是為此目的。 當Core Data限制功能或性能時,您實際上只希望在iPhone上使用SQLite。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.