I inherited a coldfusion8 site, which is using some search functionality.
I’m trying to store standardized database querys into stored procedures. Since I’m a newbie on both Coldfusion and MySQL I’m now wondering whether I can do this in 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 & ")">
The search can either be keyword or index (AAA, BBB) based. I’m still trying to understand what is happending, but so far I think if the user enters a string like:
string1, string2, string3 string4
The first part loops through the four strings (delimiter comma and space) and querys the database for matching keywords. It then creates a new cond_cats variable, which is used when the actual search takes place. I guess it replaces the search strings, with matching categories, but I’m not sure here, as the result will be
AND (1=2 OR category1 = 12345 OR category2 = 88888 )
Which is appended to the actual search query.
My questions:
Is there a way in MySQL to split the user-entered search string, so I’m able to run the loop? The second part should be an out-parameter of the stored procedure, shouldn’t it? If this is run before every search, should it be a stored procedure at all or should I keep using a database query?
Thanks for some input!
From what you described, I am not seeing much benefit to wrapping it in a stored procedure/function. Databases are not really optimized for string manipulation. While looping is possible, the equivalent sql code is usually far less elegant. Plus it may require the use of dynamic sql (or a temp table to do it safely).
However, looking over your code I believe you could eliminate the second
cfloopaltogether by using a singleIN (....)clause instead of constructing a seriesORconditions. (The two are equivalent.)Just modify the first query to retrieve only categories for the desired types ie “AAA” and “BBB”.
Then use ValueList to feed the results into your second query. It is possible you may even be able to merge your two queries into one. But that all depends on the complexity of your search query.
EDIT: I think you could still use valueList. Just add a
CASEstatement to the first query that separates the matching values into two columns:Then generate a list of the values in each column:
Finally use those lists within your search query.