这是我第一次注意到ColdFusion的这种行为。我在更新查询以使用<cfqueryparam>
时遇到了这个问题。该代码在 ColdFusion 8 平台上运行。我没有关于它在这个版本之外的行为的参考。
此外,我们通常会使用<cfqueryparam>
作为插入的值,这就是促使调查此问题的原因。
对于此示例,我们假设"first_string"和"second_string"分别包含一些文本,例如标题和一些带有<textarea>
表单帖子换行符的段落文本。
我们还可以假设 "md5_hashed_value" 列的 SQL 数据类型是 char(32(。
场景 1:
<cfset hashed_value = hash(first_string & second_string, "MD5")>
<cfquery name="my_query" datasource="#my_datasource_name#">
INSERT INTO my_table
(
md5_hashed_value
)
VALUES
(
'#hashed_value#'
)
</cfquery>
在上面的第一种方案中,将创建一个哈希值。
场景 2:
<cfquery name="my_query" datasource="#my_datasource_name#">
INSERT INTO my_table
(
md5_hashed_value
)
VALUES
(
'#hash(first_string & second_string, "MD5")#'
)
</cfquery>
在第二种情况下,计算的哈希值与第一种情况不同。
场景 3
<cfquery name="my_query" datasource="#my_datasource_name#">
INSERT INTO my_table
(
md5_hashed_value
)
VALUES
(
<cfqueryparam value="#hash(first_string & second_string, "MD5")#" CFSQLType="CF_SQL_CHAR">
)
</cfquery>
在第三种方案中,插入到数据库中的值与在第一种方案中插入的值相同。
为什么会这样?hash(( 函数在所有场景中都以相同的方式调用。它在代码中的位置是唯一的区别。当直接在 SQL 查询中调用 hash(( 而不是通过<cfqueryparam>
值或<cfset>
调用时,似乎发生了一些奇怪的事情。
这是我半生不熟的猜测。
<cfquery></cfquery>
与<cfsavecontent></cfsavecontent>
不完全相同。我不认为&
正在执行正常的字符串连接。所以这是对我的假设的检验。试试这些:
<cfset hashed_value = hash("" &first_string & second_string, "MD5")>
<cfquery name="my_query" datasource="#my_datasource_name#">
INSERT INTO my_table
(
md5_hashed_value
)
VALUES
(
'#hashed_value#'
)
</cfquery>
这样做和以前一样吗?我怀疑确实如此。
<cfquery name="my_query" datasource="#my_datasource_name#">
INSERT INTO my_table
(
md5_hashed_value
)
VALUES
(
'#hash("" & first_string & second_string, "MD5")#'
)
</cfquery>
这样做和以前一样吗?我怀疑它没有。
解决方法
<cfquery name="my_query" datasource="#my_datasource_name#">
DECLARE @md5_hashed_value = '#hash(first_string & second_string, "MD5")#'
INSERT INTO my_table
(
md5_hashed_value
)
VALUES
(
@md5_hashed_value
)
</cfquery>
虽然这没有<cfqueryparam>
的所有好处,但至少它参数化了您的查询