11

我在 ColdFusion 中编码,但试图留在 cfscript 中,所以我有一个函数允许我传入查询以运行它 <cfquery blah > #query# </cfquery>

但是,不知何故,当我构造查询sql = "SELECT * FROM a WHERE b='#c#'" 并将其传入时,ColdFusion 已将单引号替换为 2 个单引号。所以它成为 WHERE b=''c''最终查询。

我尝试了很多不同的方法来创建字符串,但我不能让它只留下一个引号。即使进行字符串替换也没有效果。

知道为什么会这样吗?在这个项目期间,它破坏了我在 cfscript 中生活的希望

4

4 回答 4

18

根据设计,ColdFusion 在<cfquery>标签内插入变量时会转义单引号。

要做你想做的事,你需要使用这个PreserveSingleQuotes()功能。

<cfquery ...>#PreserveSingleQuotes(query)#</cfquery>

但是,这并没有解决您所面临的 SQL 注入的危险。

Using<cfqueryparam>还允许您的数据库缓存查询,这在大多数情况下会提高性能。

阅读旧的 Ben Forta 专栏Brad Wood 最近发表的一篇文章可能会有所帮助,以了解有关使用<cfqueryparam>.

于 2008-11-05T21:10:25.370 回答
6

正如其他人所说,您的问题的答案是使用preserveSingleQuotes(...)

但是,您真正想要的解决方案不是以这种方式动态构建查询。很糟糕很糟糕。

将您的 SQL 放入 cfquery 标记中,并根据需要使用任何 ifs/switches/etc,并确保所有CF 变量都使用该cfqueryparam标记。

(注意,如果您在 ORDER BY 子句中使用变量,则需要手动转义任何变量;cfqueryparam 不能在 ORDER BY 子句中使用)

于 2008-11-05T23:09:04.460 回答
4

<cfquery>当您使用以下语法时,ColdFusion 会自动转义标签中的单引号:

SELECT * FROM TABLE WHERE Foo='#Foo#'

如果您想保留单引号,则#Foo#必须调用#PreserveSingleQuotes(Foo)#.

请注意,自动转义仅适用于变量值,不适用于函数结果。

SELECT * FROM TABLE WHERE Foo='#LCase(Foo)#' /* Single quotes are retained! */

鉴于此,该函数PreserveSingleQuotes()(请参阅Adob​​e LiveDocs)只不过是对值的“空操作”——将其转换为函数结果以绕过自动转义。

于 2008-11-05T21:32:58.367 回答
0

我投票赞成戴夫的回答,因为我认为他做得很好。

然而,我想补充一点,还有几个为 ColdFusion 设计的不同工具,可以简化您可能执行的许多常见 SQL 任务。有一个由 Steve Bryant 编写的名为DataMgr的非常轻量级的工具,以及来自 Mark Mandel的Transfer , Reactor最初由 Doug Hughes 创建,我开发了一个名为DataFaucet的工具。这些都有自己的长处和短处。就我个人而言,我认为您倾向于认为 DataFaucet 可以让您在 cfscript 中保持最佳状态,并使用多种语法来构建不同类型的查询。

这里有一些例子:

qry = datasource.select_avg_price_as_avgprice_from_products(); //(requires CF8)

qry = datasource.select("avg(price) as avgprice","products"); 

qry = datasource.getSelect("avg(price) as  avgprice","products").filter("categoryid",url.categoryid).execute();

qry = datasource.getSelect(table="products",orderby="productname").filter("categoryid",url.categoryid).execute();


该框架确保 cfqueryparam 始终与这些过滤语句一起使用,以防止 sql 注入攻击,并且插入、更新和删除语句的语法类似。(有一些简单的规则可以避免 sql-injection。)

于 2009-01-05T00:11:24.550 回答