在使用cfscript查询时使用查询参数出现错误

9

这是我的代码:

var qryStr = "
            UPDATE templates_email 
            SET title = :title, test_emails = :testEmail, body = :body
            WHERE id = :templateID";

q = New Query();
q.setSQL(qryStr);
q.addParam(name="title", value="#arguments.title#", cfsqltype="cf_sql_char");
q.addParam(name="body", value="#arguments.templateContent#", cfsqltype="cf_sql_char");
q.addParam(name="testEmail", value="#arguments.test_emails#", cfsqltype="cf_sql_char");
q.addParam(name="templateID", value="#arguments.id#", cfsqltype="cf_sql_integer");

return q.execute().getResult();

这是错误信息:

在指定参数列表中找不到参数'body WHERE'

SQL: UPDATE templates_email SET title = :title, test_emails = :testEmail, body = :body WHERE id = :templateID

错误发生在C:\ColdFusion9\CustomTags\com\adobe\coldfusion\query.cfc的第108行

我只能假设我在SQL参数的结构上犯了一些错误,但无法确定具体哪里有问题。请问有人能看出我在这里做错了什么吗?

1
你尝试过交换列的顺序,使得“body”不是最后一列吗?如果是这样,你是否收到了类似的错误,但这次是针对新的最后一列? - Jake Feasel
嗨,杰克。是的,我试过了,最后一个列也出现了相同的错误。楼下马克的解释非常准确地说明了问题所在。 - Jason
3个回答

14

从参数中获取解析器不会在返回值上进行标记化,只会在空格上进行(这真的很麻烦)。尝试以下操作:

var qryStr = "
    UPDATE templates_email 
    SET title = ( :title ), test_emails = ( :testEmail ), body = ( :body )
    WHERE ( id = :templateID )
";

()会消除解析器无法识别:参数何时开始和结束的任何问题。


非常准确!谢谢马克!感激不尽。 - Jason
我最初没有注意到你在括号和参数之间有空格 - 这些是很重要的,没有它们,它就无法正常工作。慷慨的空格胜利! - RaeLehman
4
你的解释有点误导。问题在于它不是按空格进行分词,而是按空格字符。它认为制表符和换行符也是参数名称的一部分。在参数名称后面添加一个单个空格字符(甚至不需要使用括号)也可以解决这个问题。话虽如此,使用括号更好,因为当某人触摸文件时,他们的编辑器可能设置为移除尾随空格。 - Kip

6

这个错误是因为你的SQL语句中存在制表符和换行符。通常情况下,我会运行下面的函数来移除这些字符。

string function cleanSQL(required string sqlStatement)
    output="false"
{
return trim(reReplace(arguments.sqlStatement, "\t|\n", " ", "all"));
}

因此,您的setSQL()可以如下所示:

q.setSQL(cleanSQL(qryStr))

或者简单地说:
q.setSQL(reReplace(qryStr, "\t|\n", " ", "all"))

0

ColdFusion 在解析 SQL 字符串以使用参数时可能会混淆。解决这个问题最简单的方法是在每个参数后面加上一个空格。

由于某些文本编辑器可能会删除尾随空格(例如在保存时),因此我会在每行末尾的任何空格后面包含一个空注释。

var qryStr = "
    UPDATE templates_email 
    SET title = :title , test_emails = :testEmail , body = :body /**/
    WHERE id = :templateID /**/
";

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接