xcode打开sqlite3数据库的遇到的问题以及数据库操作方法

本文介绍了在Xcode中使用SQLite3时遇到的问题,特别是sqlite3_prepare_v2()函数返回非零值的情况。通过检查数据库路径、复制数据库文件到正确位置来解决问题。同时,详细阐述了SQLite数据库执行SQL语句的过程,包括编译SQL、绑定参数、执行语句、获取数据和释放内存。最后,展示了简单的SQLite数据库操作函数调用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当调用 sqlite3_prepare_v2() 函数的时候,是一个将SQL语句编译为sqlite内部一个结构体(sqlite3_stmt).该结构体中包含了将要执行的的SQL语句的信息.

       通常情况下,应该是返回0。还有一些时候是返回其他数值。我以1为例,简单介绍一下错误解决的思路和方法:

我们尝试用以下代码来进行测试:

// Get the path to the documents directory and append the databaseName

NSString*documentPaths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);

NSString *documentsDir = [documentPaths objectAtIndex:0];

databasePath= [documentsDirstringByAppendingPathComponent:databaseName];

   NSFileManager*fileManager = [NSFileManagerdefaultManager];

  BOOL success = [fileManagerfileExistsAtPath:databasePath];

      上面的这个path,我们可以看到,我们需要连接的数据库的那个路径。有时候,如果你的工程创建好了以后,在运行时会把database复制到这个路径下面。如果中途数据库发生了变化,随之有可能没有拷贝过去,那么这个路径下的数据库文件会和你工程里面的不一致。也许这个path下面的是一个大小为0字节的空数据库。所以通常即便是发现了数据库的存在,但是也不能保证你数据库的结构体是正确的。因此必须确保该数据库是所需要添加的数据库。操作方法如下:

        NSString*defaultDBPath           =[[[NSBundlemainBundle]resourcePath]stringByAppendingPathComponent:@"databaseName"];

success = [fileManagercopyItemAtPath:defaultDBPathtoPath:databasePath error:&error];

if(!success) 

   NSAssert1(0,@"数据库附加失败!'%@'.", [errorlocalizedDescription]);

else 

   NSLog(@"数据库附加成功");

 

简要说明一下SQLite数据库执行SQL语句的过程 
** 调用sqlite3_prepare()将SQL语句编译为sqlite内部一个结构体(sqlite3_stmt).该结构体中包含了将要执行的的SQL语句的信息. 
** 如果需要传入参数,在SQL语句中用'?'作为占位符,再调用sqlite3_bind_XXX()函数将对应的参数传入.
** 调用sqlite3_step(),这时候SQL语句才真正执行.注意该函数的返回值,SQLITE_DONE和SQLITE_ROW都是表示执行成功, 不同的是SQLITE_DONE表示没有查询结果,象UPDATE,INSERT这些SQL语句都是返回SQLITE_DONE,SELECT查询语句在 查询结果不为空的时候返回SQLITE_ROW,在查询结果为空的时候返回SQLITE_DONE. 
** 每次调用sqlite3_step()的时候,只返回一行数据,使用sqlite3_column_XXX()函数来取出这些数据.要取出全部的数据需要 反复调用sqlite3_step(). (注意, 在bind参数的时候,参数列表的index从1开始,而取出数据的时候,列的index是从0开始). 
** 在SQL语句使用完了之后要调用sqlite3_finalize()来释放stmt占用的内存.该内存是在sqlite3_prepare()时分配的. 

       ** 如果SQL语句要重复使用,可以调用sqlite3_reset()来清楚已经绑定的参数. 

 

下面是我的打算的函数调用方式。引用的SqliteHelper之后,里面的方法可以直接调用。

 [SqliteHelperopen];

catArray= [[NSMutableArrayalloc]init];

[SqliteHelperGetAllCat:catArray];

self.DataArray=catArray;

[catArrayrelease];

 

.h文件中的定义部分。 

 

#import "SqliteHelper.h"

static sqlite3 *database_ = nil;

@implementationSqliteHelper

 

@synthesize databaseName;

@synthesize databasePath;

 

+可以理解为Static函数的写法把。 

open函数不用太多介绍。上一篇里面有详细的讲解。 

 +(BOOL) open{

databaseName=@"mydatabase.sqlite";

// Get the path to the documents directory and append the databaseName

NSArray*documentPaths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);

NSString *documentsDir = [documentPaths objectAtIndex:0];

databasePath= [documentsDirstringByAppendingPathComponent:databaseName];

   NSFileManager * fileManager = [NSFileManager defaultManager];

    BOOL find = [fileManager fileExistsAtPath:path];

   

    if (find) {

       NSLog(@"Database file have already existed.");

        if(sqlite3_open([path UTF8String], &database_) != SQLITE_OK) {

            sqlite3_close(database_);

           NSLog(@"Error: open database file.");

            returnNO;

        }

        returnYES;

    }

else{

       sqlite3_close(database_);

       NSLog(@"Error: open database file.");

        returnNO;

    }

   returnNO;

}

 

 这个SelectAll的一个方法。 不过目前看来还是不够抽象。因为就目前来看,还是具体问题需要具体分析的, 比如不同的结构,目前还无法查询到一个不同的结果,这是不可以通用的,至少表格的存储数据类型,和顺序的不同,是有很大的差异的。 还是有很大需要完善的地方把。目前也只是提供一个思路给大家参考。功能实现的同时,不要把这门OO的语言抛在脑后,时常想起面向对象。。面向对象。。。   

+(void)GetAllCat:(NSMutableArray*)catRet withSQL:(char *)sql

{

 

//[self checkAndCreateDatabase:databasePath withname:databaseName];

sqlite3_stmt *statement = nil;

if(sqlite3_open([databasePathUTF8String], &database_) ==SQLITE_OK

{

//sql ="SELECT * FROM SubCat";

int test = sqlite3_prepare_v2(database_, sql, -1, &statement, NULL);

if (sqlite3_prepare_v2(database_, sql, -1, &statement, NULL) != SQLITE_OK

{

NSLog(@"Error: failed to prepare statement with message:get channels.");

}

while (sqlite3_step(statement) == SQLITE_ROW

{

NSString*aName = [NSStringstringWithUTF8String:(char*)sqlite3_column_text(statement,1)];

NSString*catID = [NSStringstringWithUTF8String:(char*)sqlite3_column_text(statement,0)];

int catid2 = [catID intValue];

int catid    = sqlite3_column_int(statement, 0);

cat* cattable = [[catallocinit];

cattable.catId = catid;

if(aName)

{

cattable.catname = aName;

}

[catRet addObject:cattable];

[cattable release];

}

}

    sqlite3_finalize(statement);

} 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值