无法从 IOS 中的 sqlite 获取值
Posted
技术标签:
【中文标题】无法从 IOS 中的 sqlite 获取值【英文标题】:cannot fetch value from sqlite in IOS 【发布时间】:2015-04-22 12:24:26 【问题描述】:表值:
ID=1 CUSTOMERID=1 NAME=John EMAIL=email USERNAME=usernaeme
我正在使用此代码通过此代码从 Usertable 中获取 customerId
@try
//CustomerIdField=@"admin";
// customerUsername=@"admin";
NSLog(@"the value of customerusername is %@",customerUsername);
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
NSLog(@"inside function");
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"EBook.db" ]];
const char *dbpath;
@try
dbpath = [databasePath UTF8String];
NSLog(@"the const char is %s",dbpath);
@catch (NSException *exception)
NSLog(@"the exception3 is %@",exception);
if (sqlite3_open(dbpath, &Ebookreaderdb) == SQLITE_OK)
NSString *selectSQL = [NSString stringWithFormat: @"SELECT CUSTOMERID FROM Usertable WHERE EMAIL=\"%@\"",customerUsername];
sqlite3_stmt *selstatement;
const char *select_stmt = [selectSQL UTF8String];
//NSMutableArray *resultArray = [[NSMutableArray alloc]init];
if (sqlite3_prepare_v2(Ebookreaderdb,
select_stmt, -1, &selstatement, NULL ) == SQLITE_OK)
NSLog(@"inside sqlite OK"); //this prints in log
if (sqlite3_step(selstatement) == SQLITE_ROW)
NSLog(@"inside sqlite ROW"); // this is also printing in log
NSString *userInfoStr = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selstatement,1)];
NSLog(@"val is %@",userInfoStr);
char *tmp = sqlite3_column_text(selstatement,1);
if (tmp == NULL)
CustomerIdField = nil;
else
CustomerIdField = [[NSString alloc] initWithUTF8String:tmp];
CustomerIdField = [[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(selstatement,1)];
NSLog(@"inside customer is %@",CustomerIdField);
// [resultArray addObject:name];
else
NSLog(@"Not found");
// return nil;
sqlite3_reset(selstatement);
但我得到了这个异常Newpjtonfriday[2165:84017] the exception is 2 *** +[NSString stringWithUTF8String:]: NULL cString
我用谷歌搜索了上面的结果,到处都说该值为 null,这就是发生异常的原因。但在我的情况下,价值就在那里。
因为代码 NSLog(@"内部 sqlite ROW");
进入日志意味着表中存在一行。但无法获取它。
请帮忙
【问题讨论】:
顺便说一句,不要使用stringWithFormat
来构建SQL 语句。使用?
占位符和sqlite3_bind_text
函数(令人困惑的是,它使用从一开始的索引,与sqlite3_column_text
的从零开始的索引不同)。
您调用了sqlite3_reset
(用于将绑定列重置为准备好的语句,因此可以再次执行该语句)并且您显然打算调用sqlite3_finalize
(释放内存)。将reset
替换为finalize
。另外,您的意思是在此处打开数据库而不是关闭它吗?就个人而言,我会将数据库的打开与 SQL 语句的执行分开,但可以做任何你想做的事情,但只要确保每个打开都有其相应的关闭调用。不用说,这些烦人的小细节让像 FMDB 这样的库如此引人注目......
【参考方案1】:
我认为这是一个错字:
@"SELECT CUSTOMERID FROM Usertable WHERE EMAIL=\"%@\"",customerUsername;
您传递的是用户名而不是电子邮件?或者你的意思是SELECT ... WHERE USERNAME=
?
此外,也不需要任何 @try
/@catch
块,因为我看不到该代码如何引发 Objective-C 异常。
最后一件事;为了避免 SQL 注入攻击,您应该将值绑定到您的语句中,而不是像您在此处所做的那样将它们格式化为字符串。
【讨论】:
【参考方案2】:小建议如果您刚开始在 ios 上进行开发,请尝试使用一些库 (FMDB to easy work with SQLite) 以使某些任务更直接。
回答您的问题 如果表中有任何行,请尝试“SELECT * FROM Usertable”。 其次,您应该检查行中的值是否不为 NULL。 要获得简单的解决方案,请使用 Datum SQLite Free(Mac os X) 之类的东西,或者您可以使用 SELECT COUNT 来确保表中有任何行。 尝试您的选择,如果应用程序返回行但您的列中没有值,这意味着您在写入数据库逻辑时遇到问题但在读取逻辑中没有问题,并且您正在尝试获取在您想要的列上具有空值的行。那就是为什么这种方法不起作用:
[NSString stringWithUTF8String:]: NULL cString
它抛出了一个异常,因为你没有字符串并试图将 NULL 发送到方法。
【讨论】:
【参考方案3】:sqlite3_column_text
索引号是从零开始的,而不是从一开始的。因此,这一行:
char *tmp = sqlite3_column_text(selstatement, 1);
应该是:
char *tmp = sqlite3_column_text(selstatement, 0);
顺便说一句,您对这个tmp
变量的处理是在使用它之前检查以确保它不是NULL
的一种谨慎方式。不幸的是,在同一例程的其他地方,您直接使用 sqlite3_column_text
值(这就是您的应用程序崩溃的原因,而不是优雅地报告错误)。您在此处对sqlite3_column_text
进行了多次冗余调用。我建议使用您在此 tmp
变量中使用的模式。
【讨论】:
【参考方案4】:让我给你我的建议,我尝试了你刚才所做的,我也得到了错误。然后我做了一些谷歌搜索,找到了这个链接
http://www.raywenderlich.com/913/sqlite-tutorial-for-ios-making-our-app
只需修改这些代码
char *tmp = sqlite3_column_text(selstatement,1);
if (tmp == NULL)
CustomerIdField = nil;
else
CustomerIdField = [[NSString alloc] initWithUTF8String:tmp];
CustomerIdField = [[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(selstatement,1)];
NSLog(@"inside customer is %@",CustomerIdField);
到
int tmp = sqlite3_column_int(selstatement,0);// my case it is int
char *nameChars = (char *) sqlite3_column_text(selstatement, 1);// here is the change occuring please refer this
NSString *name = [[NSString alloc] initWithUTF8String:nameChars]; // there are two steps first fetch as char, then change to String
NSLog(@"customerid is %d",tmp);
NSLog(@"customer name is %@",name);
试试这个,它对我有用..
我认为问题在于您直接将 coustomerId 作为字符串获取
在你的情况下,试试这个
char *custId = (char *) sqlite3_column_text(selstatement, 0);
NSString *customerId = [[NSString alloc] initWithUTF8String:custId];
:-)
【讨论】:
以上是关于无法从 IOS 中的 sqlite 获取值的主要内容,如果未能解决你的问题,请参考以下文章
无法从 VS2019 中的 Boost 属性树映射值中获取值()
如何获取存储在 iOS 持久性 sqlite 数据库中的值?