假设有一个SQL表Fruit
id | name
--- ------
1 | 'apples'
2 | 'pears'
3 | 'kiwi'
4 | 'bananas, peaches and plumbs'
给出以下查询
<cfquery name="qAllFruit" datasource="#DSN#">
SELECT name FROM Fruit
</cfquery>
<cfquery name="qLeftoverFruit" datasource="#DSN#">
SELECT name FROM Fruit
WHERE name NOT IN (<cfqueryparam CF_SQL_TYPE="CF_SQL_VARCHAR"
value="#ValueList(qAllFruit.name)#"
list="yes" />)
</cfquery>
然后qLeftoverFruit
将错误地返回1行:bananas, peaches and plumbs
,因为展开的cfqueryparam
列表的解释不正确:
WHERE name NOT IN ('apples','pears','kiwi','bananas','peaches and plumbs')
有没有办法在使用cfqueryparam
标记和ValueList
时更正此问题?
更新以下是您可以用来重新创建此问题的要点:http://gist.github.com/a642878c96b82b21b52c
答案 0 :(得分:5)
@Daniel Mendel,我认为问题在于ColdFusion使用的默认分隔符。您的数据中包含',',CF中的默认分隔符为','顺便提一下。
像这样更改您的查询 -
WHERE name NOT IN ( <cfqueryparam CFSQLType="CF_SQL_VARCHAR"
value="#ValueList(qTags.tag,';' )#"
list="Yes" separator=";" />
)
只需将valueList中的分隔符更改为“;”默认为',',并将QueryParam分隔符设置为';'。
答案 1 :(得分:0)
此问题提供了两个示例。从CF退一步,考虑单独在一个查询中完成这项工作。对于问题中的查询:
<cfquery name="qLeftoverFruit" datasource="#DSN#">
SELECT name FROM Fruit
WHERE name NOT IN (SELECT name FROM Fruit)
</cfquery>
使用github.com上的示例:
<cfquery name="qTest" dbtype="query">
SELECT id FROM qTags
WHERE tag IN (SELECT tag FROM qTags)
</cfquery>
这些单个查询基本上执行两种查询方法的逻辑。它消除了使用cfqueryparam的需要,处理潜在的巨大列表,以及确定“安全”分隔符的缺陷。
但是,我不确定为什么需要这个查询。它应该总是返回一个空查询(来自问题的查询)或所有记录(来自github.com的查询)。两个查询之间是否存在原始问题中未提及的中间步骤?