sqlite3_mprintf - 我应该总是使用 %Q 而不是 %s 作为格式说明符吗?

gor*_*333 6 sqlite

摘自关于 sqlite3_mprintf() API 的 SQLite 参考

http://www.sqlite.org/c3ref/mprintf.html

"%Q 选项的工作方式与 %q 类似,但它还会在整个字符串的外部添加单引号。此外,如果参数列表中的参数是 NULL 指针,%Q 将替换文本 "NULL"(不带单引号) .”

使用 %q 时,我们必须小心始终在它周围使用单引号,例如

char *zText = "It's a happy day!";
char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
Run Code Online (Sandbox Code Playgroud)

总是使用 %Q 而不是 %q 似乎更方便,如下所示:

char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
Run Code Online (Sandbox Code Playgroud)

我的问题 - 是否有一个有效的用例,其中 '%q' 更合适或更有效?或者我可以安全地使用 %Q 代替所有语句中的 %s 吗?

Dav*_*itz 4

一切都是为了以安全的方式创建 SQL 语句,以最大限度地减少 SQL 注入的可能性。

你应该更喜欢%q所有%s的时间。

%q选项的工作方式类似于%s它替换参数列表中的以 null 结尾的字符串。但%q也加倍了每个'\''角色。%q设计用于在字符串文字内使用。通过加倍每个'\''字符,它可以转义该字符并允许将其插入到字符串中。

与 相比,具有%Q更多优势%q

%Q 选项的工作方式与 %q 类似,只是它还在整个字符串的外部添加单引号。此外,如果参数列表中的参数是 NULL 指针,则 %Q 替换文本“NULL”(不带单引号)。

这意味着它将添加单引号并将 null 指针呈现为"NULL"字符串内的字符串文字。

如您所见,这取决于您想做什么。如果您可以添加单引号并且"NULL"可以简单地使用生成行为%Q(我认为这对于 SQL 语句中的参数值非常有意义)。也许有时您不想要这种行为,那么您可以退回到%q.