表值:
ID = 1 CUSTOMERID = 1 NAME = John 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里面”);
进入日志意味着表中存在一行。但无法取得它。
请帮忙
答案 0 :(得分:2)
我认为这是一个错字:
@"SELECT CUSTOMERID FROM Usertable WHERE EMAIL=\"%@\"",customerUsername;
您是在传递用户名而不是电子邮件?或者你的意思是SELECT ... WHERE USERNAME=
?
此外,不需要任何@try
/ @catch
块,因为我无法看到该代码如何抛出Objective-C异常。
最后一件事;为了避免SQL注入攻击,您应该将值绑定到您的语句中,而不是将它们格式化为字符串,就像您在此处所做的那样。
答案 1 :(得分:2)
小建议如果您刚刚开始在iOS上开发,请尝试使用一些库(FMDB to easy work with SQLite)来更直接地完成某项任务。
回答您的问题 如果表中有任何行,请尝试“SELECT * FROM Usertable”。 其次,您应该检查行中的值是否不为NULL。 要获得简单的解决方案,请使用Datum SQLite Free(Mac OS X)或者您可以使用SELECT COUNT来确保表中有任何行。 尝试你的选择,如果应用程序返回行,但你的列中没有值,这意味着你有写入DB逻辑而不是读取逻辑的问题,并且你试图获取你想要的列上具有空值的行。那就是为什么这种方法不起作用:
[NSString stringWithUTF8String:]: NULL cString
它抛出异常,因为你没有字符串并且试图向方法发送NULL。
答案 2 :(得分:2)
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
变量的模式。
答案 3 :(得分:1)
让我给你我的建议我尝试了你刚做的事情,我也得到了错误。然后我做了一些谷歌搜索,发现了这个链接
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直接取为String
在你的情况下,试试这个
char *custId = (char *) sqlite3_column_text(selstatement, 0);
NSString *customerId = [[NSString alloc] initWithUTF8String:custId];
: - )