sqlite3_mprintf
- sqlite3_mprintf()函数原型:
-
char *sqlite3_mprintf(const char*,...);
- sqlite3_mprintf()的作用是将结果写入到sqlite3_malloc()获取的内存中,例程返回的字符串应该使用sqlite3_free()进行释放,如果无法申请到足够的内存,则会返回NULL指针;
- 它同c库函数 sprintf()类似,实现一些额外的格式化。对所有常用的printf()格式化选项都适用。另外还有非常用选项:%q, %Q, %z;
- %q选项的作用类似于%s,它会替换了参数列表中以空字符结尾的字符串%q,同时他会将单引号字符转义,有助于防止SQL注入攻击;
- 示例:
-
char * zText =“这是快乐的一天!”; char * zSQL = sqlite3_mprintf(“INSERT INTO table VALUES('%q')”,zText); sqlite3_exec(db,zSQL,0,0,0); sqlite3_free(ZSQL)
- 因为使用了%q格式字符串,所以zText中的'\''字符被转义,生成的SQL如下所示:
-
INSERT INTO table1 VALUES('这是快乐的一天!')
- 作为一般规则,在将文本插入字符串文字时,应始终使用%q而不是%s。
- %Q选项的作用类似于%q,除了它还在整个字符串的外部添加单引号。此外,如果参数列表中的参数是NULL指针,则%Q替换文本“NULL”(不带单引号);
-
char * zSQL = sqlite3_mprintf(“INSERT INTO table VALUES(%Q)”,zText); sqlite3_exec(db,zSQL,0,0,0); sqlite3_free(ZSQL);
- 即使zText变量是NULL指针,上面的代码也会在zSQL变量中呈现正确的SQL语句。
- “%z”格式化选项的作用类似于“%s”,但添加了在读取字符串并将其复制到结果中之后,在输入字符串上调用sqlite3_free()。
从程序看 %s, %q, %Q之间的区别
-
char *str_he = "合"; char *str_fen = "分"; //初始化表 for(rc = 0; rc < 16; rc++) { sql = sqlite3_mprintf("INSERT INTO RELAY VALUES ('%d', '%s','%s', '2019-7-12');", rc, str_he, str_fen); sqlite3_exec(db, sql, 0, 0, &zErrMsg); } rc = sqlite3_get_table(db, "SELECT * FROM RELAY", &dbresult, &nRow, &nColum, &zErrMsg); if(rc == SQLITE_OK) { index = nColum; for(i = 0; i < nRow; i++) { for(j = 0; j < nColum; j++) { printf("%d--%s : %s\n", i, dbresult[j], dbresult[index++]); // ++index; } printf("----------------------------------------------\n"); } }
- 输出结果:
-
0--ID : 0 0--C_STATUS : 合 0--W_STATUS : 分 0--TIME : 2019-7-12 ---------------------------------------------- 1--ID : 1 1--C_STATUS : 合 1--W_STATUS : 分 1--TIME : 2019-7-12 ---------------------------------------------- 2--ID : 2 2--C_STATUS : 合 2--W_STATUS : 分 2--TIME : 2019-7-12 ---------------------------------------------- 。。。。。
- 将 %s 改为 %q ,输出结果:
-
0--ID : 0 0--C_STATUS : 合 0--W_STATUS : 分 0--TIME : 2019-7-12 ---------------------------------------------- 1--ID : 1 1--C_STATUS : 合 1--W_STATUS : 分 1--TIME : 2019-7-12 ---------------------------------------------- 2--ID : 2 2--C_STATUS : 合 2--W_STATUS : 分 2--TIME : 2019-7-12 ----------------------------------------------
。。。。。。
- 将 %s 改为 %Q,输出结果:
-
0--ID : 0 0--C_STATUS : 合 0--W_STATUS : 分 0--TIME : 2019-7-12 ---------------------------------------------- 1--ID : 1 1--C_STATUS : 合 1--W_STATUS : 分 1--TIME : 2019-7-12 ---------------------------------------------- 2--ID : 2 2--C_STATUS : 合 2--W_STATUS : 分 2--TIME : 2019-7-12 ---------------------------------------------- 。。。。。。
- 从上面的结果来看,当插入的字符串不为空指针时,三者之间并没有多大差别。
- 将字符串设置为NULL
-
char *str_he = NULL; char *str_fen = NULL;
- %s 输出结果
-
0--ID : 0 0--C_STATUS : 0--W_STATUS : 0--TIME : 2019-7-12 ---------------------------------------------- 1--ID : 1 1--C_STATUS : 1--W_STATUS : 1--TIME : 2019-7-12 ---------------------------------------------- 2--ID : 2 2--C_STATUS : 2--W_STATUS : 2--TIME : 2019-7-12 ---------------------------------------------- 。。。。。。
- %q 输出结果
-
0--ID : 0 0--C_STATUS : (NULL) 0--W_STATUS : (NULL) 0--TIME : 2019-7-12 ---------------------------------------------- 1--ID : 1 1--C_STATUS : (NULL) 1--W_STATUS : (NULL) 1--TIME : 2019-7-12 ---------------------------------------------- 2--ID : 2 2--C_STATUS : (NULL) 2--W_STATUS : (NULL) 2--TIME : 2019-7-12 ---------------------------------------------- 。。。。。。
- %Q输出结果
-
0--ID : 0 0--C_STATUS : (null) 0--W_STATUS : (null) 0--TIME : 2019-7-12 ---------------------------------------------- 1--ID : 1 1--C_STATUS : (null) 1--W_STATUS : (null) 1--TIME : 2019-7-12 ---------------------------------------------- 2--ID : 2 2--C_STATUS : (null) 2--W_STATUS : (null) 2--TIME : 2019-7-12 ---------------------------------------------- 。。。。。。
- 当需要插入的字符为NULL时,%s 并没有将NULL插入到表中,但是%q, %Q能够将NULL插入到表中,只是大小写不一样;