我想你可以猜到我遇到的问题。我将文件名插入到 C++ Builder 中的 sql 数据库中。有些文件的名称中有撇号。这会破坏 sql 插入查询。解决此问题的常用方法是将您希望成为字段值一部分的撇号加倍。
例如,如果我想将 'george's' 添加到字段 'owner',则 sql 查询将是“插入表(所有者)值('george''s')”
我对那一点没意见。我只需要将单撇号替换为双撇号。AnsiString 似乎没有内置函数。有没有一种简单的方法可以做到这一点而不必包含一个全新的头文件?
我想你可以猜到我遇到的问题。我将文件名插入到 C++ Builder 中的 sql 数据库中。有些文件的名称中有撇号。这会破坏 sql 插入查询。解决此问题的常用方法是将您希望成为字段值一部分的撇号加倍。
例如,如果我想将 'george's' 添加到字段 'owner',则 sql 查询将是“插入表(所有者)值('george''s')”
我对那一点没意见。我只需要将单撇号替换为双撇号。AnsiString 似乎没有内置函数。有没有一种简单的方法可以做到这一点而不必包含一个全新的头文件?
其实我自己也有答案...
item = StringReplace( item, "'", "''", TReplaceFlags() <<rfReplaceAll );
(所以 AnsiString 毕竟有一个内置的替换功能)
编辑:添加了代码标签,以便我们可以区分不同的引号
我没有使用过 AnsiString,但基本上我会执行以下操作:
执行此操作的常用方法是使用准备好的语句,而不是生成自己的 sql。查找SQL Injection的原因之一是它不好。基本上,如果在您的应用程序中的任何地方,您忘记将任何 sql 语句中的引号加倍,并且攻击者可以以某种方式将值提交到该 sql 语句中,那么您的数据库就会被黑客入侵。(有关可能发生的事情的幽默示例,请参阅此 xkcd 漫画。)
在 C++ Builder 中,您正在寻找AnsiQuotedStr
函数,在SysUtils
. 它的倒数是AnsiExtractQuotedStr
。它们不是AnsiString
类型本身的方法,因为它们不需要深入了解类型的内部结构。
不过,更重要的是,您应该使用参数化查询。如果您用于数据库访问的组件不支持这些组件,则获取不同的数据库库。不乏数据库选择,因此您可以对功能挑剔,参数化查询应该靠近列表的顶部。
请注意,尽管有名称,但在 Delphi 和 C++ Builder 2009 中,这些AnsiX
函数接受UnicodeString
参数,而不是。AnsiString
如果你这样替换它会发生什么
item = StringReplace( item, "'", "\'", TReplaceFlags() );