Cfqueryparam'd从函数生成查询

RRK*_*RRK 1 coldfusion coldfusion-8 cfml

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

<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>
Run Code Online (Sandbox Code Playgroud)

然后在查询中像这样调用它


    SELECT * 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添加到查询中吗?

Ada*_*ron 5

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

首先,当你停下来思考它时,这有点愚蠢,不是吗?(对不起,我的意思并不是那种意味深长的方式).并且不要感到难过:我认为我们在某个阶段都做到了这一点.

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

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

因此,使用CFML代码生成字符串的代码直到(4)才会执行,但需要在(2)处返回.除非你能旅行,否则就行不通.

我在我的博客中讨论过这个问题:" ColdFusion请求/响应过程 "

你可以做一些事情:

  1. 不要像这样编写动态泛型SQL.我们所有人在第一次启动时都会这样做,但很快就会意识到动态/通用SQL从来都不是解决任何问题的好方法.
  2. 使用其中一个已存在的DB抽象层.CF 9+附带了Hibernate支持.
  3. 如果使用Query.cfc而不是<cfquery>,则可以将占位符放入参数中,并将参数数据单独传递给查询.
  4. 将动态代码写入磁盘,然后再写入磁盘include.这将破坏编译时/运行时的事情.它会很慢,因为包含的文件需要在运行之前进行编译.它很丑.

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