如何从我的 sqlite 数据库中获取数据
Posted
技术标签:
【中文标题】如何从我的 sqlite 数据库中获取数据【英文标题】:how to fetch data from my sqlite database 【发布时间】:2013-10-06 05:29:40 【问题描述】:我是 iphone 开发者的初学者。我已经创建了 sqlite 数据库。我制作了学生数据表,我想显示来自 sqlite 数据库的数据,我使用从下面的代码中获取数据,但是有一些错误,我无法从我在下面的代码中使用的数据库中获取数据..
#import <Foundation/Foundation.h>
// This includes the header for the SQLite library.
#import <sqlite3.h>
@interface DBConnection : NSObject
//reference to the SQLite database.
@private
sqlite3 *g_database;
@property (nonatomic,assign,readonly) sqlite3 *database;
+ (DBConnection *) sharedConnection;
+ (BOOL) executeQuery:(NSString *)query;
+ (NSMutableArray *) fetchResults:(NSString *)query;
+ (int) rowCountForTable:(NSString *)table where:(NSString *)where;
+ (void) errorMessage:(NSString *)msg;
+ (void) closeConnection;
#include <sys/xattr.h>
@interface DBConnection (Private)
- (void) createEditableCopyOfDatabaseIfNeeded;
- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL;
- (void) initializeDatabase;
@end
@implementation DBConnection
static DBConnection *conn = NULL;
@synthesize database = g_database;
+ (DBConnection *) sharedConnection
if (!conn)
conn = [[DBConnection alloc] initConnection];
return conn;
#pragma mark -
#pragma mark Static Methods
+ (BOOL) executeQuery:(NSString *)query
BOOL isExecuted = NO;
sqlite3 *database = [DBConnection sharedConnection].database;
sqlite3_stmt *statement = nil;
const char *sql = [query UTF8String];
if (sqlite3_prepare_v2(database, sql, -1, &statement , NULL) != SQLITE_OK)
//NSLog(@"Error: failed to prepare agenda query statement with message '%s'.", sqlite3_errmsg(database));
//NSString *errorMsg = [NSString stringWithFormat:@"Failed to prepare query statement - '%s'.", sqlite3_errmsg(database)];
//[DBConnection errorMessage:errorMsg];
//NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
return isExecuted;
// Execute the query.
if(SQLITE_DONE == sqlite3_step(statement))
isExecuted = YES;
// finlize the statement.
sqlite3_finalize(statement);
statement = nil;
return isExecuted;
+ (NSMutableArray *) fetchResults:(NSString *)query
NSMutableArray *results = [NSMutableArray arrayWithCapacity:0];
sqlite3 *database = [DBConnection sharedConnection].database;
sqlite3_stmt *statement = nil;
const char *sql = [query UTF8String];
if (sqlite3_prepare_v2(database, sql, -1, &statement , NULL) != SQLITE_OK)
//NSLog(@"Error: failed to prepare fetch results statement with message '%s'.", sqlite3_errmsg(database));
NSString *errorMsg = [NSString stringWithFormat:@"Failed to prepare query statement - '%s'.", sqlite3_errmsg(database)];
[DBConnection errorMessage:errorMsg];
//NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
return results;
while (sqlite3_step(statement) == SQLITE_ROW)
id value = nil;
NSMutableDictionary *rowDict = [NSMutableDictionary dictionaryWithCapacity:0];
for (int i = 0 ; i < sqlite3_column_count(statement) ; i++)
/*
if (strcasecmp(sqlite3_column_decltype(statement,i),"Boolean") == 0)
value = [NSNumber numberWithBool:(BOOL)sqlite3_column_int(statement,i)];
else */
if (sqlite3_column_type(statement,i) == SQLITE_INTEGER)
value = [NSNumber numberWithInt:(int)sqlite3_column_int(statement,i)];
else if (sqlite3_column_type(statement,i) == SQLITE_FLOAT)
value = [NSNumber numberWithFloat:(float)sqlite3_column_double(statement,i)];
else
if (sqlite3_column_text(statement,i) != nil)
value = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)];
else
value = @"";
if (value)
[rowDict setObject:value forKey:[NSString stringWithUTF8String:sqlite3_column_name(statement,i)]];
[results addObject:rowDict];
////NSLog(@"rowDict -- %@", rowDict);
sqlite3_finalize(statement);
statement = nil;
return results;
+ (int) rowCountForTable:(NSString *)table where:(NSString *)where
int tableCount = 0;
NSString *query = @"";
if (where != nil && ![where isEqualToString:@""])
query = [NSString stringWithFormat:@"SELECT COUNT(*) FROM %@ WHERE %@",
table,where];
else
[NSString stringWithFormat:@"SELECT COUNT(*) FROM %@",
table];
sqlite3_stmt *statement = nil;
sqlite3 *database = [DBConnection sharedConnection].database;
const char *sql = [query UTF8String];
if (sqlite3_prepare_v2(database, sql, -1, &statement , NULL) != SQLITE_OK)
return 0;
if (sqlite3_step(statement) == SQLITE_ROW)
tableCount = sqlite3_column_int(statement,0);
sqlite3_finalize(statement);
return tableCount;
+ (void) errorMessage:(NSString *)msg
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"ERROR" message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
+ (void) closeConnection
sqlite3 *database = [DBConnection sharedConnection].database;
if (sqlite3_close(database) != SQLITE_OK)
//NSAssert1(0, @"Error: failed to close database with message '%s'.", sqlite3_errmsg(g_database));
NSString *errorMsg = [NSString stringWithFormat:@"Failed to open database with message - '%s'.", sqlite3_errmsg(database)];
[DBConnection errorMessage:errorMsg];
- (id) initConnection
if (self == [super init])
//database = g_database;
if (g_database == nil)
// The application ships with a default database in its bundle. If anything in the application
// bundle is altered, the code sign will fail. We want the database to be editable by users,
// so we need to create a copy of it in the application's Documents directory.
[self createEditableCopyOfDatabaseIfNeeded];
// Call internal method to initialize database connection
[self initializeDatabase];
return self;
// Creates a writable copy of the bundled default database in the application Documents directory.
- (void)createEditableCopyOfDatabaseIfNeeded
// First, test for existence.
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dbDirectory = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]]];
if (![fileManager fileExistsAtPath:dbDirectory])
[fileManager createDirectoryAtPath:dbDirectory withIntermediateDirectories:NO attributes:nil error:nil];
[self addSkipBackupAttributeToItemAtURL:[[[NSURL alloc] initFileURLWithPath:dbDirectory isDirectory:YES] autorelease]];
NSString *writableDBPath = [dbDirectory stringByAppendingPathComponent:DB_NAME];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success) return;
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:DB_NAME];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success)
//NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
NSString *errorMsg = [NSString stringWithFormat:@"Failed to create writable database file with message - %@.", [error localizedDescription]];
[DBConnection errorMessage:errorMsg];
- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
const char* filePath = [[URL path] fileSystemRepresentation];
const char* attrName = "com.apple.MobileBackup";
u_int8_t attrValue = 1;
int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
return result == 0;
// Open the database connection and retrieve minimal information for all objects.
- (void)initializeDatabase
// The database is stored in the application bundle.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dbDirectory = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]]];
NSString *path = [dbDirectory stringByAppendingPathComponent:DB_NAME];
////NSLog(@"SQLite Root: %s", [path UTF8String]);
// Open the database. The database was prepared outside the application.
if (sqlite3_open([path UTF8String], &g_database) != SQLITE_OK)
// Even though the open failed, call close to properly clean up resources.
sqlite3_close(g_database);
g_database = nil;
//NSAssert1(0, @"Failed to open database with message '%s'.", sqlite3_errmsg(g_database));
NSString *errorMsg = [NSString stringWithFormat:@"Failed to open database with message - '%s'.", sqlite3_errmsg(g_database)];
[DBConnection errorMessage:errorMsg];
// Save all changes to the database, then close it.
- (void)close
if (g_database)
// Close the database.
if (sqlite3_close(g_database) != SQLITE_OK)
//NSAssert1(0, @"Error: failed to close database with message '%s'.", sqlite3_errmsg(g_database));
NSString *errorMsg = [NSString stringWithFormat:@"Failed to open database with message - '%s'.", sqlite3_errmsg(g_database)];
[DBConnection errorMessage:errorMsg];
g_database = nil;
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
// "dehydrate" all data objects - flushes changes back to the database, removes objects from memory
请提供适用于我的代码的任何建议和源代码..
谢谢……
【问题讨论】:
您遇到什么错误?在不知道错误是什么的情况下,我们无法提供任何帮助。 请解释您遇到的错误是什么 【参考方案1】:我建议你使用FMDB - 一个客观的 C 语言包装器。这很容易,并且会节省您的大量精力。
【讨论】:
【参考方案2】:我同意选择一个开源库作为开始,特别是如果您是初学者。这是我写的一个针对初学者的 SQLite 库:TankDB
有很多示例可供查看,以便能够快速实现您在上面尝试做的事情。
【讨论】:
以上是关于如何从我的 sqlite 数据库中获取数据的主要内容,如果未能解决你的问题,请参考以下文章
使用 Core Data 一对多关系从 JSON 数组填充 sqlite 数据库
SQLite - 如何使用 ROW_NUMBER() OVER