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 }

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。