1

有一个搜索查询,还有一个我用来生成查询元素的函数

<cffunction name="GetSearchQuery" output="true" returntype="string" access="public">
    <cfargument name="arrayName" type="array" required="yes">
    <cfargument name="columnName" type="string" required="yes">
    <cfargument name="searchtype" type="string" required="no" default="wildcard">
    <cfset var o = "">
    <cfset var i = "">
    <cfset var search_item = "">
    <cfset search_item = "(">
    <cfloop from="1" to="#ArrayLen(Arguments.arrayName)#" index="o">
        <cfif Arguments.arrayName[o][1] EQ #Arguments.columnName#>
        <cfloop from="2" to="#ArrayLen(Arguments.arrayName[o])#" index="i">
            <cfset search_item = search_item & #Arguments.columnName#>
            <cfswitch expression="#Arguments.searchtype#">
                <cfcase value="wildcard">
                    <cfset search_item = search_item & ' LIKE 
                    <cfqueryparam value="%' & #Arguments.arrayName[o][i]# & '%"> AND '>
                </cfcase>
                <cfcase value="startswith">
                    <cfset search_item = search_item & ' LIKE 
                    <cfqueryparam value="' & #Arguments.arrayName[o][i]# & '%"> AND '>
                </cfcase>
                <cfcase value="endswith">
                    <cfset search_item = search_item & ' LIKE 
                    <cfqueryparam value="%' & #Arguments.arrayName[o][i]# & '"> AND '>
                </cfcase>
                <cfcase value="exactmatch">
                    <cfset search_item = search_item & ' = 
                    <cfqueryparam value="' & #Arguments.arrayName[o][i]# & '"> AND '>
                </cfcase>
            </cfswitch>
        </cfloop>
        </cfif>
    </cfloop>
    <cfif Len(search_item) GT 4>
    <cfset search_item = Left(search_item, Len(search_item)-4) & ") ">
    </cfif>
    <cfreturn search_item>
</cffunction>

然后在查询中这样调用它

    选择 * FROM #request.tablename#
      WHERE #utilObj.GetSearchQuery(arrsearch, "photonumber", true)# OR
            #utilObj.GetSearchQuery(arrsearch, "takenby", true)# OR
            #utilObj.GetSearchQuery(arrsearch, "category", true)# OR
            #utilObj.GetSearchQuery(arrsearch, "area", true)# OR
            #utilObj.GetSearchQuery(arrsearch, "description", true)#

但这会导致查询出错

但是如果函数中没有 cfqueryparam 的话,这个就可以了。
例如。<cfset search_item = search_item & ' LIKE "%' & #Arguments.arrayName[o][i]# & '%" AND '>

无论如何,我们可以将 cfqueryparam 动态添加到查询中吗?

4

2 回答 2

5

你不能创建一个包含 CFML 的字符串并输出它,并期望它以某种方式意味着它会被实际执行。

一方面,当你停下来想一想时,这有点愚蠢,尼特?(对不起,我不是那种刻薄的意思)。不要难过:我认为我们都在某个阶段做到了这一点。

其次:CFML 在执行之前被编译。所以这个过程是(出于所有意图和目的):

  1. 请求包含代码的文件
  2. 文件中的代码被传递给 CF 编译器
  3. CF 编译器吐出 java 字节码
  4. JVM执行java字节码

因此,您使用 CFML 代码生成字符串的代码在 (4) 之前不会执行,但在 (2) 处需要返回。除非你能时间旅行,否则那是行不通的。

我在我的博客中讨论了这个:“ ColdFusion 请求/响应过程

您可以做一些 coupla 的事情:

  1. 不要像这样编写动态通用 SQL。我们所有人在刚开始时都会这样做,但很快就会意识到动态/通用 SQL 永远不是解决手头任何问题的好方法。
  2. 使用现有的数据库抽象层之一。CF 9+ 内置了 Hibernate 支持。
  3. 如果使用Query.cfc而不是<cfquery>,则可以为参数放置占位符,并将参数数据单独传递到查询中。
  4. 将您的动态代码写入磁盘,然后include将其写入磁盘。这将颠覆编译时/运行时的事情。它会很慢,因为您的包含文件需要在运行之前进行编译。它很丑。

该列表按我处理此问题的优先顺序排列。

于 2013-08-06T12:44:32.273 回答
2

这是对“无论如何我们可以将 cfqueryparam 动态添加到查询中吗?”的回应。有,但你必须在 cfquery 块内进行。这样的事情是可以的:

<cfquery>
    select SomeFields
    from SomeTables
    where 1 = 1
    <cfif something>
        and somefield = <cfqueryparam value="#SomeVariable#">
    </cfif>
</cfquery>

你不能做的,至少不是在版本 9 和更低版本上,是让查询参数成为变量的一部分。换句话说,这不会编译。

WhereClause = "where 1=1";
if (something)
WhereClause &= ' and somefield = <cfqueryparam value="#SomeVariable#">';

这或多或少是您正在尝试的。

于 2013-08-07T00:25:49.783 回答