如何将搜索字符串coldfusion循环转换为MySQL存储过程?

如何将搜索字符串coldfusion循环转换为MySQL存储过程?,mysql,stored-procedures,loops,coldfusion,Mysql,Stored Procedures,Loops,Coldfusion,我继承了一个coldfusion8站点,该站点正在使用一些搜索功能 我试图将标准化的数据库查询存储到存储过程中。由于我是Coldfusion和MySQL的新手,我现在想知道我是否可以在MySQL中做到这一点: <cfquery datasource="db" name="find_cats"> SELECT wg.no, wg.type, wg.keywords, wg.lang FROM cats AS wg <cfloop list="search

我继承了一个coldfusion8站点,该站点正在使用一些搜索功能

我试图将标准化的数据库查询存储到存储过程中。由于我是Coldfusion和MySQL的新手,我现在想知道我是否可以在MySQL中做到这一点:

<cfquery datasource="db" name="find_cats">
    SELECT wg.no, wg.type, wg.keywords, wg.lang
    FROM cats AS wg 
    <cfloop list="searchForm.cats_search_string" delimiters=", " item="tag">
      WHERE wg.keywords LIKE <cfqueryparam value='%#tag#%' cfsqltype='cf_sql_varchar'> AND
    </cfloop>
    wg.lang = <cfqueryparam value="#Session.lang#" cfsqltype="cf_sql_varchar">
</cfquery>
<cfset cond_cats = "AND (1=2">
    <cfoutput query="find_cats">
        <!--- check if found category belongs to either AAA or BBB classifcation --->
        <cfif wg.type is "AAA">
            <cfset cond_cats = cond_cats & " OR categoryID1 = #wg.no#">
        </cfif>
        <cfif wg.typ is "BBB">
            <cfset cond_cats = cond_cats & " OR categoryID2 = #wg.no#">
        </cfif>
    </cfoutput>
    <cfset cond_cats = cond_cats & ")">
第一部分循环四个字符串(分隔符逗号和空格),并查询数据库中匹配的关键字。然后,它创建一个新的cond_cats变量,在实际搜索时使用该变量。我猜它会用匹配的类别替换搜索字符串,但我不确定这里的结果会是什么

AND (1=2 OR category1 = 12345 OR category2 = 88888 )
它被附加到实际的搜索查询中

   WHERE 1 = 2

   <cfif listLen(firstList)>
         OR categoryID1 IN ( <cfqueryparam value="#firstList#" list="true" cfsqltype="cf_sql_integer"> )
   </cfif>

   <cfif listLen(secondList)>
         OR categoryID2 IN ( <cfqueryparam value="#secondList#" list="true" cfsqltype="cf_sql_integer"> )
   </cfif>
我的问题:
在MySQL中有没有办法分割用户输入的搜索字符串,这样我就可以运行循环了?第二部分应该是存储过程的out参数,不是吗?如果在每次搜索之前都运行此命令,那么它到底应该是一个存储过程,还是应该继续使用数据库查询


谢谢你的意见

我认为您应该尝试在mysql中使用“全文”索引。

从您描述的内容来看,将其包装到存储过程/函数中并没有什么好处。数据库并没有真正针对字符串操作进行优化。虽然循环是可能的,但等效的sql代码通常不那么优雅。另外,它可能需要使用动态sql(或临时表来安全地执行)

但是,查看您的代码,我相信您可以通过使用单个子句而不是构造一系列的
条件来完全消除第二个
cfloop
。(两者是等价的。)

只需修改第一个查询,以仅检索所需类型(即“AAA”和“BBB”)的类别

然后在每列中生成一个值列表:

     <cfset firstList  = valueList(find_cats.ID1Values)>
     <cfset secondList = valueList(find_cats.ID2Values)>

最后,在搜索查询中使用这些列表

   WHERE 1 = 2

   <cfif listLen(firstList)>
         OR categoryID1 IN ( <cfqueryparam value="#firstList#" list="true" cfsqltype="cf_sql_integer"> )
   </cfif>

   <cfif listLen(secondList)>
         OR categoryID2 IN ( <cfqueryparam value="#secondList#" list="true" cfsqltype="cf_sql_integer"> )
   </cfif>
其中1=2
或()
或()

这不是我的问题。。。我有一个全文搜索,但除此之外,还有更细粒度的搜索条件,如上面所述。我正在努力使这成为一个存储过程,因此对此的任何帮助都将不胜感激。谢谢!谢谢你的信息。我不确定它是否有用,但I valueList可能有用。听起来你的问题是“这作为存储过程会更好吗?”我不知道。因此,上面的代码演示了如何更高效、更安全地编写cfquery(无需所有串联ie动态sql)不过,你可以把这个问题留一段时间,征求其他意见。对不起。我不清楚。问题回答正确。我的示例代码有一个错误,因此您的代码片段适用于错误的示例代码。问题是categoryID1应该是categoryID1和CategoryId2。ID1是体育用品产品分类的名称,ID2是服装的名称。因此,我需要检查两个索引中是否有任何关键字匹配任何类别,并返回每个索引中的类别编号(如果有)。我的示例只轮询了ID1,因此IN将起作用。我还没有找到一种方法将它与两个单独的ID一起使用。我已经编辑了我的问题。再次感谢您的投入!我认为使用valueList仍然是可能的。查看我的更新响应。我是否需要为MySql包含带valueList的分隔符?
SELECT  wg.no
        , CASE WHEN wg.type = 'AAA' THEN wg.no ELSE NULL END AS ID1Values
        , CASE WHEN wg.type = 'BBB' THEN wg.no ELSE NULL END AS ID2Values
...
     <cfset firstList  = valueList(find_cats.ID1Values)>
     <cfset secondList = valueList(find_cats.ID2Values)>
   WHERE 1 = 2

   <cfif listLen(firstList)>
         OR categoryID1 IN ( <cfqueryparam value="#firstList#" list="true" cfsqltype="cf_sql_integer"> )
   </cfif>

   <cfif listLen(secondList)>
         OR categoryID2 IN ( <cfqueryparam value="#secondList#" list="true" cfsqltype="cf_sql_integer"> )
   </cfif>