在我的ColdFusion 11应用程序中,使用SQL Server 2008-R2,我在CF组件中有以下cfquery标记:
<cfquery name="result_set" dataSource="#request.dsn_name#">
select name, state from myTable #REReplace(where_clause,"''","'","ALL")#
</cfquery>
这里where_clause
是一个变量。CF将一个单引号替换为两个,因此我使用REReplace函数将两个单引号重新替换为一个。所以我的查询发生了变化,例如从
select name, state from myTable WHERE name IN (''ABC'')
到此:
select name, state from myTable WHERE name IN ('ABC')
问题是当名称列值也包含一个引号时。例如
select name, state from myTable WHERE name IN ('Smith's bat')
在这种情况下,查询会失败。我该如何解决此类案件。我尝试过PreserveSingleQuotes,但它也有同样的问题,列中的值带有单引号。
更新
这个应用程序是几年前由使用ColdFusion MX 7的人开发的。原作者正在根据特定条件为where_clause变量创建动态字符串。这是一个长的cfs文件,有几个条件用于创建where _ clause的动态字符串。因此,使用cfqueryparam可能不合适,或者可能需要对客户不允许的代码进行彻底检查。
这是一个令人讨厌的问题。恐怕我只能想出一个令人讨厌的"解决方案"。
- 替换值分隔符:
<cfset where_clause = replace(where_clause, "''", "§§", "ALL")>
- 然后转义实际的单引号:
<cfset where_clause = replace(where_clause, "'", "'", "ALL")>
- 现在恢复替换并规范化分隔符:
<cfset where_clause = replace(where_clause, "§§", "'", "ALL")>
把它放在一起:
<cfset substitution = "§§"> <!--- use whatever char sequence works best for your data --->
<!--- fallback in case the substitution is part of your data --->
<cfif where_clause contains substitution>
<cfset substitution = "°°°">
<!---
you can basically start looping through a bunch of alternatives
or even expand the substition with an additional character
...you get the idea
--->
</cfif>
<cfset where_clause = replace(where_clause, "''", substitution, "ALL")>
<cfset where_clause = replace(where_clause, "'", "'", "ALL")>
<cfset where_clause = replace(where_clause, substitution, "'", "ALL")>
<cfquery...
正如你所看到的,这仍然是一个很大的问题,有一天可能会失败。但是,只要您必须处理where_clause
变量,可能就没有更好的选择了。
您需要使用函数PreserveSingleQuotes,即:
<cfquery name="result_set" dataSource="#request.dsn_name#">
select name, state from myTable #PreserveSingleQuotes(REReplace(where_clause,"''","'","ALL"))#
</cfquery>
祝你今天过得愉快!