sqlite3语句对象的生命周期--举例说明
语句对象的生命周期:
1.使用sqlite3_prepare_v2或相关的函数创建这个对象
2.使用sqlite3_bind_*()给宿主参数绑定值
3.通过调用sqlite3_step一次或多次来执行这个sql
4.使用sqlite3_reset()重置这个语句,然后回到第2步,这个过程做0次或多次
5.使用sqlite3_finalize()销毁这个对象
例子:
1 //查询指定商品 2 - (Product *)selectProductById:(int)proId { 3 4 // 1.打开数据库 5 sqlite3 *db = [DB openDB]; 6 // 2.准备sql语句 7 NSString *sql = @"select * from products where pro_id = ?"; 8 /* 9 3.创建指向编译好的sql准备语句的指针 10 能够使用sqlite3_step()执行的编译好的准备语句的指针,如果错误发生, 11 它被置为NULL,如:输入的文本不包括sql语句。编译好的sql语句完成使 12 用后,使用sqlite3_finalize()删除它。 13 */ 14 sqlite3_stmt *stmt = nil; 15 /* 16 4.将数据库指针sql,文本sql和sql的跟随指针整合,为下边的执行做准备 17 将sql文本转换成一个准备语句对象,同时返回这个对象的指针。这个接口需 18 要一个数据连接指针db以及一个要准备的包含SQL语句的文本sql,它实际并 19 不执行(evaluate)这个SQL语句,它仅仅为执行准备这个sql语句 20 推荐在任何的程序中都使用sqlite3_prepare_v2这个函数,sqlite3_prepare只是用于前向兼容 21 */ 22 int result = sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, nil); 23 // 5.如果准备过程成功,则返回SQLITE_OK,否则返回错误代码, 24 if (result == SQLITE_OK) { 25 /* 26 给参数绑定值,stmt指向sql准备语句,1表示的是spl语句中第一个?参数, 27 第三个proId表示用于替换?处的参数 28 */ 29 30 /* 31 宿主参数(host parameters) 32 在传给sqlite3_prepare_v2()的sqld的语句文本或者他的变量中,满足如下模板的文字将被替换成一个参数: 33 1.? 34 2.?NNN,NNN代表数字 35 3.:VVV,VVV代表字符 36 4.@VVV 37 5.$VVV 38 上面的这些模板中,NNN代表一个数字,VVV代表一个字符数字标记符(例如:222表示名称为222的标记符), 39 sql语句中的参数(变量)通过上面的几个模板来指定,如: 40 "sleect ? from ?"这个语句中指定了两个参数,sqlite语句中的第一个参数的索引值是1,这就知道这 41 个语句之呢过的两个参数的索引分别为1和2,使用"?"的话黑背自动给予索引值,而使用"?NNN"则可以自己 42 指定参数的索引值为NNN。":VVV"表示一个名为"VVV"的参数,它也有一个索引值,被自动指定。 43 而sqlite3_bind*()是用来给这些参数赋值的 44 */ 45 46 sqlite3_bind_int(stmt, 1, proId); 47 48 /* 49 6.sqlite3_step(stmt)这相当于一个遍历器,根据sql中的命令,一行一行的对数据库中的数据进行遍历, 50 遍历出得数据可以通过sqlite3_column取出 51 */ 52 /* 53 这个过程用于执行由前面sqlite3_prepare创建的准备语句。这个语句执行到结果的第一行可用的位置。继续 54 前进到结果的第二行的话,只需再次调用sqlite3_step(),继续调用sqlite3_step(),直到这个语句完成, 55 那些不反悔结果的语句(如:INSERT,UPTDATE,或DELETE),sqlite3_step()只执行一次就返回 56 57 返回值:函数的返回值基于创建sqlite3_stmt参数所使用的函数,假如是使用老版本的接口sqlite3_prpare() 58 和sqlite3_prepare16(),返回值会是SQLITE_BUSY,SQLITE_DONE,SQLITE_ROW,SQLITE_ERROR或 59 SQLITE_MISUSE,而v2版本的接口sqlite3_prepare_v2()和sqlite3_prepare16_v2()则会同时 60 返回这些结果码和扩展结果码。 61 */ 62 int stepResult = sqlite3_step(stmt); 63 if (stepResult == SQLITE_ROW) { 64 Product *pro = [[Product alloc] init]; 65 // 7.利用sqlite3_column*()取出某一行的某一列的值 66 /* 67 sqlite3_column() 68 这个过程从执行sqlite3_step()执行一个准备语句得到的结果集的当前行中返回一个列。每次 69 sqlite3_step得到一个结果集的列停下后,这个过程就可以被多次调用区查询这个行的各列的值。 70 对列操作是由多个函数,均以sqlite3_column为前缀 71 参数:第一个为准备语句对象的指针stmt,第二个参数是这一行中想要返回的列的索引。最左边的 72 一列的索引号是0,行的列数可以使用sqlite3_column_count()获得 73 */ 74 pro.proId = sqlite3_column_int(stmt, 0); 75 const char *name = (const char *)sqlite3_column_text(stmt, 1); 76 pro.proName = [NSString stringWithUTF8String:name]; 77 pro.proPrice = sqlite3_column_double(stmt, 2); 78 const char *date = (const char *)sqlite3_column_text(stmt, 3); 79 pro.proDate = [NSString stringWithUTF8String:date]; 80 const char *ad = (const char *)sqlite3_column_text(stmt, 4); 81 pro.proAd = [NSString stringWithUTF8String:ad]; 82 [DB closeDB]; 83 sqlite3_finalize(stmt); 84 return [pro autorelease]; 85 86 } else { 87 [DB closeDB]; 88 sqlite3_finalize(stmt); 89 } 90 } 91 return nil; 92 } 93 94 //查询所有商品 95 - (NSArray *)selectAllProducts { 96 97 // 1.打开数据库 98 sqlite3 *db = [DB openDB]; 99 // 2.创建sql语句 100 NSString *sql = @"select * from products"; 101 // 3.创建准备语句指针 102 sqlite3_stmt *stmt = nil; 103 // 4.创建准备语句 104 int result = sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, nil); 105 // 5.如果准备完毕 106 if (result == SQLITE_OK) { 107 NSMutableArray *proArr = [[NSMutableArray alloc] init]; 108 while (sqlite3_step(stmt) == SQLITE_ROW) { 109 @autoreleasepool { 110 Product *pro = [[Product alloc] init]; 111 pro.proId = sqlite3_column_int(stmt, 0); 112 const char *name = (const char *)sqlite3_column_text(stmt, 1); 113 pro.proName = [NSString stringWithUTF8String:name]; 114 pro.proPrice = sqlite3_column_double(stmt, 2); 115 const char *date = (const char *)sqlite3_column_text(stmt, 3); 116 pro.proDate = [NSString stringWithUTF8String:date]; 117 const char *ad = (const char *)sqlite3_column_text(stmt, 4); 118 pro.proAd = [NSString stringWithUTF8String:ad]; 119 [proArr addObject:pro]; 120 [pro release]; 121 } 122 sqlite3_finalize(stmt); 123 [DB closeDB]; 124 return proArr; 125 } 126 127 } else { 128 sqlite3_finalize(stmt); 129 [DB closeDB]; 130 } 131 132 return nil; 133 }
sqlite3_exec的应用:
sqlite3_exec是sqlite3_prepare_v2、sqlite3_step()和sqlite3_finalize()的封装,能让程序多次执行sql语句而不需要写许多的重复代码
如果sqlite3_exec的第三个参数回调函数指针不为空,那么他会为灭个来自执行的SQL语句的结果行调用(也就是说回调函数会调用多次),第四个参数是传给回调函数的第一个参数,如果回调函数指针为空,那么回调不会发生同时结果行被忽略。
如果在执行sql语句中有错误放生,那么当前的语句的执行被停止,后续的语句也被跳过。第五个参数不为空的时候,它被分配内存并写入错误信息,所以在sqlite3_exec后面需要调用sqlite3_free去释放这个对象以防止内存泄露。
1 //插入商品 返回值根据需要自己设定 2 - (BOOL)insertProduct:(Product *)pro { 3 4 // 1.打开数据库 5 sqlite3 *db = [DB openDB]; 6 // 2.准备sql语句 7 NSString *sql = [NSString stringWithFormat:@"insert into products values (%d,‘%@‘,%f,‘%@‘,‘%@‘)",pro.proId,pro.proName,pro.proPrice,pro.proDate,pro.proAd]; 8 // 3.执行sql语句 9 /* 10 sqlite3_exec是sqlite3_prepare_v2、sqlite3_step()和sqlite3_finalize()的封装,能让程序 11 多次执行sql语句而不需要写许多的重复代码 12 如果sqlite3_exec的第三个参数回调函数指针不为空,那么他会为灭个来自执行的SQL语句的结果行调用( 13 也就是说回调函数会调用多次),第四个参数是传给回调函数的第一个参数,如果回调函数指针为空,那么 14 回调不会发生同时结果行被忽略。 15 如果在执行sql语句中有错误放生,那么当前的语句的执行被停止,后续的语句也被跳过。第五个参数不为空 16 的时候,它被分配内存并写入错误信息,所以在sqlite3_exec后面需要调用sqlite3_free去释放这个对象 17 以防止内存泄露。 18 */ 19 20 int result = sqlite3_exec(db, sql.UTF8String, nil, nil, nil); 21 // 4.关闭数据库,要写在if上面,return将会结束一切返回 22 [DB closeDB]; 23 if (result == SQLITE_OK) { 24 NSLog(@"成功"); 25 return YES; 26 }else { 27 NSLog(@"失败:%d",result); 28 return NO; 29 } 30 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。