ColdFusion and loading message during loading big data - sql
I have a cfm page with several queries (one cfinvoke in a cfloop from a query). When the page is loading, the loading of data take a long time before to be completely displayed.
Data are displayed in an html table thanks to the cfloop. I saw that the display is progressively displayed.
I would like to know how to improve that with a lazy loading (with a loading message or icon).
my script:
<!-------------------------------- GET DATA ON THE MEETING ----------------------------- START --->
<cftry>
<cfquery name="qry_reunion" datasource="#application.datasource#">
SELECT
R.*
FROM REUNION R
LEFT JOIN MODULES_V M on M.MOD_ID = R.I_MODULE_SIC_ID
INNER JOIN APP_GEN_CODE_T B on B.ST_CODE = R.REUN_CNRE_ST_CODE
INNER JOIN APP_GEN_CODE_T D on d.ST_CODE = R.CSRE_ST_CODE
where R.EXRC_NUMREXRC = '#form.year_source#'
and B.ST_CLASS_CODE = 'BUD_CNRE'
and d.ST_CLASS_CODE = 'BUD_CSRE'
<cfif #Searchstatut# is not "">
and R.CSRE_ST_CODE = '#Searchstatut#'
</cfif>
<cfif #Searchnumber# is not "">
and R.REUN_NUMREURO = '#Searchnumber#'
</cfif>
ORDER BY R.REUN_NUMRREUN
</cfquery>
<cfcatch type="database">
<!--- PUT THE VARIABLE errorDBquery TO 1 --> Disable the Save button of the form) --->
<cfset SESSION.errorDBquery = 1>
</cfcatch>
</cftry>
<!-------------------------------- GET DATA ON THE MEETING ------------------------------ END --->
<cfset reunionIdList= "0" />
<cfif isdefined("qry_reunion.recordcount")>
<!--- Create the list of meeting number --->
<cfloop from="1" to="#qry_reunion.recordcount#" index="i">
<!--- create a var with all REUN_NUMRREUN used in this SCRIPT --->
<cfscript>
reunionIdList &= ",";
reunionIdList &= #qry_reunion.REUN_NUMRREUN[i]#;
</cfscript>
</cfloop>
<cfif #qry_reunion.RECORDCOUNT# is 0 AND #searchorg# is not "">
<br><br><cfoutput>#application.ui_lib_Result#</cfoutput>
<cfelse>
<br>
<table class="dataTable">
<thead>
<cfoutput>
<tr>
<th title="#application.ui_lib_numero#">#application.ui_lib_numero#</th>
<th title="#application.ui_lib_organisateur#">#application.ui_lib_organisateur#</th>
<th title="#application.ui_lib_objet#">#application.ui_lib_objet#</th>
<th title="#application.ui_lib_statut#">#application.ui_lib_statut#</th>
<th title="#application.ui_lib_ville#">#application.ui_lib_ville#</th>
<th title=""> </th>
</tr>
</cfoutput>
</thead>
<tbody>
<!-------------------------------- Retrieve info on all unit ------------------------------- START --->
<cfinvoke component="service/meetings" method="getMeetingsUnitLabel" returnvariable="meetingsUnit">
<cfinvokeargument name="meetingsNumber" value="#reunionIdList#">
</cfinvoke>
<cfloop from="1" to="#qry_reunion.recordcount#" index="i">
<cfoutput>
<form action="reunion_status.cfm?mode=generalite_sta" method="post">
<tr>
<td class="cc">#qry_reunion.REUN_NUMREURO[i]#</td>
<td class="cc">
<!-------------------------------- Retrieve info on unit and check that the org_id is still active ------------------------------- START --->
<cfinvoke component="service/units" method="getUnitVersionFromMeetingOrgId" returnvariable="meetingUnitVersion">
<cfinvokeargument name="meetingOrgId" value="#qry_reunion.ORG_ID[i]#">
<cfinvokeargument name="meetingId" value="#qry_reunion.REUN_NUMRREUN[i]#">
<cfinvokeargument name="unitsArray" value="#SerializeJSON(meetingsUnit.VALUES)#">
</cfinvoke>
<cfif StructIsEmpty(meetingUnitVersion) eq false >
<cfif #meetingUnitVersion.VALUES.OBSOLETE# EQ 0>
<cfset unit ="#meetingUnitVersion.VALUES.ORG_CD#"/>
<cfelse>
<cfset unit ="#meetingUnitVersion.VALUES.ORG_CD# (obsolete)" />
</cfif>
#unit#
<cfif #meetingUnitVersion.VALUES.OBSOLETE# EQ 1 AND #meetingUnitVersion.VALUES.IS_ESTAT# eq 1>
<!--- Dsiplay a tooltip when unit is archived --->
<span id="obsoleteMeetingUnit_#i#" style="line-height:30px;">
<img class='my-tooltip' src='pictures/questionmark.gif' style='vertical-align:middle;'>
</span>
<cfset REUN_DATECREA = #DateFormat(qry_reunion.DATECREA[i], "dd/mm/yyyy")# />
<script>
var #toScript(meetingUnitVersion.VALUES.UNIT_VALID_FROM, "unitValidFrom")#;
var #toScript(meetingUnitVersion.VALUES.UNIT_VALID_TO, "unitValidTo")#;
var #toScript(meetingUnitVersion.VALUES.ORG_CD, "unitLabel")#;
var #toScript(REUN_DATECREA, "meetingCreationDate")#;
var #toScript(i, "i")#;
$("##obsoleteMeetingUnit_" + i).tooltipster({
contentAsHTML: true,
interactive: true,
animation: 'grow',
content: $("<span> was " + unitLabel + " <em>(valid from " + unitValidFrom + " to " + unitValidTo +")</em> when the meeting has been created on " + meetingCreationDate +".</span>"),
theme: 'tooltipster-shadow'
});
</script>
</cfif>
<cfelse>
Error
</cfif>
</td>
<td class="cc">#qry_reunion.REUN_OBJET[i]#</td>
<td class="cc">#qry_reunion.NATURE[i]#</td>
<td class="cc">#qry_reunion.VIL_CD[i]#</td>
<td class="cc">
<input type="hidden" name="REUN_NUMRREUN" value="#qry_reunion.REUN_NUMRREUN[i]#">
<input name="#application.ui_lib_chgt_status#" type="submit" value="#application.ui_lib_chgt_status#">
</td>
</tr>
</form>
</cfoutput>
</cfloop>
</tbody>
</table>
</cfif>
</cfif>
Some additional information:
In my DB there is a view of all Units containing current and the history of each unit.
A meeting is linked to one unit but the unit can have several records in the view. And I need to get the correct row of the unit linked to each meeting
I need to display the list of meetings in function of the filters selected in the different drop-down lists.
I create a function getMeetingsUnitLabel for getting data of all units from the list of meetings in parameter. it's allows me to use that for 1 or several meetings.
The second function getUnitVersionFromMeetingOrgId retrieve the correct record on the version of the unit used when the meeting has been created (it used the parameters retrieved from the previous function.
Thank you in advance for your help,
Seb
(Too long for a comment.)
First thing: Read about SQL injection (use <cfqueryparam>) and DOM XSS (use encodeForHtml()). Your page is full of vulnerabilities and it doesn't matter if that's just some intranet/backoffice because security is relevant everywhere.
Second thing: Learn when to use # and when you don't need them.
Finally: Measure the performance of each section. There is getTickCount() to get a rough timing delta for code execution (just don't use it for micro benchmarking). Generally you want to avoid calling heavy functions in a loop (see Big O notation), especially database/IO calls. Retrieve and process data once and then work with the resultset instead of calling subfunctions for each result. You did not tell us what your functions (getMeetingsUnitLabel and getUnitVersionFromMeetingOrgId) actually do, nor how your query performs, so it's hard to recommend anything specific right now.
Also: Consider moving the JavaScript blocks within your loop to a single script block at the end (after the loop). It will be easier to maintain that instead of fiddling around in each table row.
There is a lot of stuff going on here. Let me cover what stands out to me.
Using cfoutput
...
<cfloop from="1" to="#qry_reunion.recordcount#" index="i">
<cfoutput>
...
<tr>
<td class="cc">#qry_reunion.REUN_NUMREURO[i]#</td>
...
Is the the ColdFusion way of getting data out of a DB. It looks like how other languages do it. It should really look like this
...
<cfoutput query="qry_reunion">
...
<tr>
<td class="cc">#REUN_NUMREURO#</td>
...
Some places I have worked at really like scoping query variables. In that case it would be
...
<cfoutput query="qry_reunion">
...
<tr>
<td class="cc">#qry_reunion.REUN_NUMREURO#</td>
...
Nested calls
<cfloop
...
<cfinvoke component="service/units" method="getUnitVersionFromMeetingOrgId" returnvariable="meetingUnitVersion">
...
This is just asking to be slow. I would create an SQL user defined function or a view to do whatever this is. I want to put the data collecting work on the DB because the DB knows more about collecting and grouping and joining data than ColdFusion
Tooltip
<span id="obsoleteMeetingUnit_#i#" style="line-height:30px;">
<img class='my-tooltip' src='pictures/questionmark.gif' style='vertical-align:middle;'>
</span>
...
var #toScript(i, "i")#;
$("##obsoleteMeetingUnit_" + i).tooltipster({
contentAsHTML: true,
interactive: true,
animation: 'grow',
content: $("<span> was " + unitLabel + " <em>(valid from " + unitValidFrom + " to " + unitValidTo +")</em> when the meeting has been created on " + meetingCreationDate +".</span>"),
theme: 'tooltipster-shadow'
});
</script>
All this is way to verbose. Not to mention it is probably real slow to become interactive. If you need a fancy tool tip. The pattern should look like this:
<span class="custom_tooltip"
data-unitlabel = "#EncodeForHTMLAttribute(unitLabel)#"
data-unitvalidfrom = "#EncodeForHTMLAttribute(unitValidFrom)#"
data-unitvalidto = "#EncodeForHTMLAttribute(unitValidTo)#"
data-dtCreate = "#EncodeForHTMLAttribute(meetingCreationDate)#"
></span>
Then hook in some document.ready stuff and have it apply the tooltip stuff after everything has loaded.
Conclusion
The amount of HTML generated is about twice as big as it needs to be. All of this should be much smaller and quicker.
Related
I am trying to create basic datatables.net and coldfusion server side example but it doesnt seem to works
This example was based on this link https://datatables.net/forums/discussion/40613/datatable-jquery-server-side-with-adobe-cold-fusion-and-sql-server and i am using datatable version 1.10 On first page load, all data sucessfully loaded into #formsTable But it wont work when clicking sorting,searching and paging. It just hang with 'processing..' pageA.cfm (only show scripting part here...) <script type="text/javascript"> $(document).ready(function(){ $('#formsTable').DataTable({ processing:true, serverSide:true, ajax:{ url:'pageB.cfm' }, columns:[ {title: "id",data:'id'}, {title: "Name",data:'name'}, {title: "Emp.No",data:'empno'}, {title: "IC",data:'ic'} ] }) }) </script> pageB.cfm (server-side) <cfcontent reset="true"> <cfset listColumns = "id,emp_no,emp_name,number_id2" /> <cfset sIndexColumn = "id" /> <cfparam name="draw" default="1" type="integer" /> <cfparam name="start" default="0" type="integer" /> <cfparam name="length" default="10" type="integer" /> <cfparam name="url.sSearch" default="" type="string" /> <cfparam name="url.iSortingCols" default="0" type="integer" /> <!--- query data ---> <cfquery datasource="hrms" name="qFiltered"> select id,emp_no,emp_name,number_id2 from employee <cfif len(trim(url.sSearch))> Where ( <cfloop list="#listColumns#" index="thisColumn"> <cfif thisColumn neq listFirst(listColumns)> OR </cfif> #thisColumn# LIKE <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="%#trim(url.sSearch)#%" /> </cfloop> ) </cfif> <cfif url.iSortingCols gt 0> ORDER BY <cfloop from="0" to="#url.iSortingCols-1#" index="thisS"> <cfif thisS is not 0>, </cfif> #listGetAt(listColumns,(url["iSortCol_"&thisS]+1))# <cfif listFindNoCase("asc,desc",url["sSortDir_"&thisS]) gt 0> #url["sSortDir_"&thisS]# </cfif> </cfloop> </cfif> </cfquery> <!--- query data count ---> <cfquery dbtype="query" name="qCount"> SELECT COUNT(#sIndexColumn#) as total FROM qFiltered </cfquery> <!--- Output ---> {"draw": <cfoutput>#val(draw)#</cfoutput>, "recordsTotal": <cfoutput>#qCount.total#</cfoutput>, "recordsFiltered": <cfoutput>#qFiltered.recordCount#</cfoutput>, "aaData": [ <cfoutput query="qFiltered" startrow="#val(start+1)#" maxrows="#val(length)#"> <cfif currentRow gt (start+1)>,</cfif> { "id":#SerializeJSON(qFiltered.currentrow)#, "name":#SerializeJSON(qFiltered.emp_name)#, "empno":#SerializeJSON(qFiltered.emp_no)#, "ic": <cfif trim(qFiltered.number_id2) neq '[empty string]'> #SerializeJSON(qFiltered.number_id2)# <cfelse> "" </cfif> } </cfoutput> ] } I am stuck here , it seems that something is missing on pageB.cfm ? Edited: thanks for #user12031119 pointing out that sent parameter from pageA.cfm to pageB.cfm is different now with v1.10, so basically these parameters should be change :- sEcho : draw iDisplayStart : start iDisplayLength : length iTotalRecords : recordsTotal iTotalDisplayRecords : recordsFiltered with that change i can now click on next/prev page (paging) but still search and sorting dont work
Yes, unfortunately the code sample you're viewing on datatables.net is for legacy datatables. Under datatables 1.10.x, you will have to use the upgraded keys which version 1.10 expects in your returned json structure. It looks like you already updated pageA.cfm with the new parameters, however you also need to update your server-side return parameters in pageB.cfm. Here's a guide to upgrade to version 1.10 https://datatables.net/upgrade/1.10 Here's a guide for the new parameters for server-side 1.10 https://datatables.net/manual/server-side Edit 1 thanks to James A Mohler Edit 2 per issue noticed by myself Apparently I was mistaken that datatables only accepts an array of arrays when returned from the server. Apparently it also accepts an array of structs, which helps simplify my answer. However, this will require aliasing the columns in the select statement to match the column definitions defined in pageA.cfm. With that said, here are the changes needed. The first code modification to pageB.cfm will be to alias the columns in your select statemen to match their definition in pageA.cfm. <cfquery datasource="hrms" name="qFiltered"> select id as id, emp_no as empno, emp_name as name, number_id2 as ic from employee Once that's done, change the following in your <cfoutput> block from pageB.cfm Change sEcho to draw Change iTotalRecords to recordsTotal Change iTotalDisplayRecords to recordsFiltered Change aaData to data Use serializeJson() with the "struct" option to return an array of structs with the key values matching up to how you defined them in pageA.cfm. If you're using ACF instead of lucee, then you might have to change your column definitions in pageA.cfm to uppercase since ACF doesn't preserve case and uppercases key names. <!--- Output ---> <cfoutput> { "draw": #val(url.sEcho)#, "recordsTotal": #qCount.total#, "recordsFiltered": #qFiltered.recordCount#, "data": #serializeJson(qFiltered, "struct")# } </cfoutput>
First, check that your JSON output is valid (jsonlint.com) Then, wrap your JSON output into a cfsavecontent: <cfsavecontent variable="json"> <cfoutput> your output here </cfoutput> </cfsavecontent> Then use this code to return the JSON: <cfset lastModDate = DateFormat(Now(),'ddd, dd mmm YYYY') & ' ' & TimeFormat(DateConvert('local2Utc', Now()), 'HH:mm:ss') & ' GMT'> <cfheader name="Expires" value="#DateAdd('m', -1, Now())#"> <cfheader name="Last-Modified" value="#lastModDate#"> <cfheader name="cache-control" value="must-revalidate"> <cfheader name="Pragma" value="no-cache"> <cfcontent type="text/x-json" /> <cfoutput>#json#</cfoutput>
OK finally it works now. So this is it, basic datatables.net coldfusion/lucee server side example. Datatables Version 1.10.xx Language Coldfusion/lucee pageA.cfm (scripting) <script type="text/javascript"> $(document).ready(function(){ $('#formsTable').DataTable({ processing:true, serverSide:true, ajax:{ url:'pageB.cfm', type :'post' }, columns:[ {title: "id",data:'id'}, {title: "Name",data:'name'}, {title: "Emp.No",data:'empno'}, {title: "IC",data:'ic'} ], language: { infoEmpty: "No records available", } }) }) </script> pageB.cfm <cfcontent reset="true"> <cfset listColumns = "id,emp_no,emp_name,number_id2" /> <cfset sIndexColumn = "id" /> <cfparam name="draw" default="1" type="integer" /> <cfparam name="start" default="0" type="integer" /> <cfparam name="length" default="10" type="integer" /> <cfparam name="search" default="" type="string" /> <cfif len(form["search[value]"]) gt 0> <cfset search=form["search[value]"]> </cfif> <!--- Data set after filtering ---> <cfquery datasource="hrms" name="qFiltered"> select id,emp_no,emp_name,number_id2 from employee <cfif len(trim(search))> where ( <cfloop list="#listColumns#" index="thisColumn"> <cfif thisColumn neq listFirst(listColumns)> OR </cfif> #thisColumn# LIKE <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="%#trim(search)#%" /> </cfloop> ) </cfif> <cfif form["order[0][column]"] gt 0> ORDER BY <cfif form["order[0][column]"] eq '1'> emp_name <cfif form["order[0][dir]"] eq 'desc'>desc</cfif> </cfif> <cfif form["order[0][column]"] eq '2'> emp_no <cfif form["order[0][dir]"] eq 'desc'>desc</cfif> </cfif> <cfif form["order[0][column]"] eq '3'> number_id2 <cfif form["order[0][dir]"] eq 'desc'>desc</cfif> </cfif> </cfif> </cfquery> <!--- Total data set length ---> <cfquery dbtype="query" name="qCount"> SELECT COUNT(#sIndexColumn#) as total FROM qFiltered </cfquery> <cfif qFiltered.recordcount gt 0> <cfset recordsTotal=#qCount.total#> <cfelse> <cfset recordsTotal=0> </cfif> <!--- Output ---> {"draw": <cfoutput>#val(draw)#</cfoutput>, "recordsTotal": <cfoutput>#recordsTotal#</cfoutput>, "recordsFiltered": <cfoutput>#qFiltered.recordCount#</cfoutput>, "data": <cfif qFiltered.recordcount gt 0> [ <cfoutput query="qFiltered" startrow="#val(start+1)#" maxrows="#val(length)#"> <cfif currentRow gt (start+1)>,</cfif> { "id":#SerializeJSON(qFiltered.currentrow)#, "name":#SerializeJSON(qFiltered.emp_name)#, "empno":#SerializeJSON(qFiltered.emp_no)#, "ic": <cfif trim(qFiltered.number_id2) neq '[empty string]'> #SerializeJSON(qFiltered.number_id2)# <cfelse> "" </cfif> } </cfoutput> ] <cfelse> "" </cfif> }
How to create table for my perl output using perl cgi?
Here is my code and output i was unable to create the different row for my each line using perl? Here is my code: use strict; use warnings; use CGI; open(my $file1,"as.txt"); my $firstline=<$file1>; $firstline=~s/.*=//g; my #words=split /,/,$firstline; my $finalline=join("\n",#words); close $file1; print "Content-type:text/html\n\n" print<<"EOF"; <html><body> <table style="width:100%"> <tr> <th>UserName</th> <th>Access</th> </tr> <tr> <td>$finalline</td> <td> <input type="checkbox" value="check2" mulitple checked>Read <input type="checkbox" value="check2" mulitple>Write <input type="checkbox" value="check2" mulitple>Owner </td> </tr> </table></body></html> EOF MY OUTPUT FOR PERL (I.E $finalline) sankar morien3 i got the following table as my output in table format: UserName Access sankar morien3 Read Write Owner Expected output: UserName Access sankar Read Write Owner morien3 Read Write Owner Input file:(i.e as.txt) cskTeam = sankar, mobrien3 [csk:/] * = r #cskTeam = rw
You must know about how HTML layout will work. Even your code won't give your expected result in terminal. In html \n not make sense, <br> it is for new line in html. But this logic also won't work in your code. You are joining the array with \n, then printing the data it will execute the comment line by line what you have mentioned. First you have printing the $finalline variable so it result is sankar \n morien3 \n will not consider in html. Storing in one cell as per <td> Then you are creating the another cell which holds the permission detail. Finally your code should be as follows. #!/usr/bin/perl use warnings; use strict; use CGI; use CGI::Carp qw(fatalsToBrowser); print "Content-Type: text/html \n\n"; open my $file1,"<","as.txt"; my $firstline=<$file1>; $firstline=~s/.*=//g; my #words=split /,/,$firstline; close $file1; print<<"EOF"; <html><body> <table style="width:50%; "> <tr> <th style="text-align:left">UserName</th> <th style="text-align:left">Access</th> </tr> EOF foreach (#words) { print <<EOF; <tr> <td>$_</td> <td> <input type="checkbox" value="check2" mulitple checked>Read <input type="checkbox" value="check2" mulitple>Write <input type="checkbox" value="check2" mulitple>Owner </td> </tr> EOF } print <<EOF; </table></body></html> EOF
Outputting dynamic variables
Why can I not make my textbox show only what the user has entered? <cfinput type="text" name="firstname_#Add#" value="#form['firstname_#Add#']#" > I have also researched and tried changing to <input type="text" name="firstname_#Add#" value="<cfoutput>#form['firstname_#Add#']#</cfoutput>" > <cfloop index="Add" from="1" to="#session.checkout.quantity.pcount#" step="1"> <cfset session.checkout.info["firstname_#Add#"]=""> <cfparam name="form['firstname_#Add#']" default="session.checkout.info.firstname_#Add#"> </cfloop> <cfif structKeyExists(form, "submit")> <cfset errors = []> <cfif not arrayLen(errors)> <cfloop index="Add" from="1" to="#session.checkout.quantity.pcount#" step="1"> <cfset session.checkout.info["firstname_#Add#"]=form["firstname_#Add#"]> </cfloop> Where am I going wrong? Instead of being blank it is showing the session variable (session.checkout.info.firstname_#Add#") then instead of saving it when the user hits a link back to that page it changes what they have entered back to (session.checkout.info.firstname_#Add#"). Anyone have any ideas?
You're telling that CFPARAM to use the text "session...", not the value of "session...". This should get you what you want: <cfparam name="form['firstname_' & Add]" default="#session['checkout.info.firstname_' & Add]#">
coldfusion create list from query results
I am currently using Binding to grab values from a database. Depending on what the user selects from a pull down it shows the results from the database. Currently I am able to show one result but I need to show multiple results if the query brings back more then 1 value. Here is my current code. <cffunction name="getServiceType" access="remote" returnType="array"> <cfargument name="CATG_NAME" type="string" required="true"> <cfset var data=""> <cfset var result=ArrayNew(2)> <cfset var i=0> <cfquery name="getServiceType" datasource="#dsource#"> select distinct SRTY_NAME from Somedatabase where (CATG_SPRS_NAME = <cfqueryparam value="#ARGUMENTS.CATG_NAME#" cfsqltype="cf_sql_varchar"> OR CATG_DEPT_SPRS_NAME = <cfqueryparam value="#ARGUMENTS.CATG_NAME#" cfsqltype="cf_sql_varchar">) AND EVLN_REQD_FLAG IS NOT NULL order by SRTY_NAME </cfquery> <cfloop index="i" from="1" to="#getServiceType.recordcount#"> <cfset result[i][1]=getServiceType2.SRTY_NAME[i]> <cfset result[i][2]=getServiceType2.SRTY_NAME[i]> </cfloop> <cfreturn result> </cffunction> This generates the 1st pull down list <cffunction name="getUnion" access="remote" returnType="array"> <cfargument name="SRTY_NAME" type="string" required="true"> <cfset var result=ArrayNew(1)> <cfquery name="union_rq" datasource="#dsource#"> select U.UNI_NAME, S.SRTY_NAME from Somedatabase U JOIN Someotherdatabase S ON U.SRTY_NBR = S.SRTY_NBR where S.SRTY_NAME = <cfqueryparam value="#ARGUMENTS.SRTY_NAME#" cfsqltype="cf_sql_varchar"> </cfquery> <cfset result[1]=union_rq.UNI_NAME> <cfreturn result> </cffunction> The first list would have an option list Hotel Training and the second query should show both Maids and Cooks. Right now it only shows Maids. I tried to create a list or another array but have not be able to get it to display the results. Below is my Coldfusion call for the display. It is fine to display with commas between the results like Maids,Cooks <tr id="union"> <td></td> <td>Union Attached: <cfinput name="uni_name" bind="cfc:servicetype.getUnion({service_type})" bindonload="false" /></td></tr> Any advice would be greatly appreicated.
SQL select statement with AND and OR operators issue
I'm fetching records from the SQL Server 2000 database using Classic ASP. This is what the code I have used. ASP Code: <form name="search" method="post" onsubmit="return attention();"> <table width="60%" border="0" cellpadding="2" cellspacing="0" style="margin:0 auto"> <tr> <td colspan="2"><h1 style="color:#003399;">Search for Certificate of Analysis</h1></td> </tr> <tr> <td valign="bottom">Product number <sup style="color:#EE0000;font-size:1.3em">*</sup></td> <td valign="bottom">Lot number</td> </tr> <tr> <td width="30%" valign="top"> <input type="text" name="input1" size="20"/> </td> <td valign="top"> <input type="text" size="20" name="input2"/> <input style="background-color:#ffffff;border:0px;cursor:pointer" size="10" type="submit" name="sub" value=">>" /> </td> </tr> </table> <% if request.Form("sub") <> "" then Dim fname, lname fname= request.Form("input1") lname= request.Form("input2") session("n") = fname & lname sql = "Select * from search where cat_no_batch_no LIKE '"&request.Form("input1")&"%' OR cat_no_batch_no='"&session("n")&"'" rs.open sql, con, 1, 2 if rs.eof then response.write("Please provide a valid Cat No.") else do while not rs.eof %> <table border="1" cellpadding="5" cellspacing="0" width="60%" style="margin:0 auto; border-collapse:collapse;border-color:#999999"> <tr> <td width="50%"><%=rs("cat_no_batch_no")%></td> <td width="10%">Click to open <a target="_blank" href="http://localhost/search1/<%=rs("pdf_path")%>"><%=rs("cat_no_batch_no")%></a></td> </tr> </table> <% rs.movenext loop end if rs.close end if %> </form> Above the LIKE statement works as expected and displays multiple records which contains similar Cat No.. Issue rises when I input a Cat No in first Input box and Lot Number in another. My desired output should have been just a single record to display as I have given Cat No. and Lot Number , but it shows multiple records. I have provided the images to be more clear. In this image below I have put 6106021 as the product number so it displays two entries. In this image I have put 6106021 as the product number and 218111 as the Lot Number, it shows two entries instead of 1. This is what the issue, it should show one entry as Lot number are unique while cat number can be the same.
Read your question to yourself and think about what you are saying: You state "My desired output should have been just a single record to display as I have given Cat No. and Lot Number" But in your SQL you write where cat_no_batch_no LIKE '"&request.Form("input1")&"%' OR cat_no_batch_no='"&session("n")&"' The key words are AND vs. OR In your mind you are thinking both conditions must be true, but your query says otherwise. If you want both conditions to be true then you must use the AND operator. Naoki is on to something - you are going to have to modify your SQL depending upon which criteria are specified.
I guess you can write two separate SQL queries, according as the "Lot number" is provided or not. Your code may goes like below: if lname = "" then sql = "Select * from search where cat_no_batch_no LIKE '"&request.Form("input1")&"%'" else sql = "Select * from search where cat_no_batch_no LIKE '"&session("n")&"%'" end if I hope this could help