ColdFusion is giving error when executing database query - coldfusion

Can somebody please suggest what is wrong with this code?
<cfquery name="getPreviousDBentries" datasource="#application.datasource#">
select image, image_b,
image_c,image_d,image_e, image_f from used_listings_v2 where id = '#edit#'
</cfquery>
<cfdump var="#getPreviousDBentries#">
<cftry>
<cfquery name="updateToNull" datasource="#application.datasource#">
<cfif len(getPreviousDBentries.image) neq 0>
Update used_listings_v2 SET image = NULL where id = '#edit#'
</cfif>
<cfif len(getPreviousDBentries.image_b) neq 0>
Update used_listings_v2 SET image_b = NULL where id = '#edit#'
</cfif>
<cfif len(getPreviousDBentries.image_c) neq 0>
Update used_listings_v2 SET image_c = NULL where id = '#edit#'
</cfif>
<cfif len(getPreviousDBentries.image_d) neq 0>
Update used_listings_v2 SET image_d = NULL where id = '#edit#'
</cfif>
<cfif len(getPreviousDBentries.image_e) neq 0>
Update used_listings_v2 SET image_e = NULL where id = '#edit#'
</cfif>
<cfif len(getPreviousDBentries.image_f) neq 0>
Update used_listings_v2 SET image_f = NULL where id = '#edit#'
</cfif>
</cfquery>
<cfcatch>
<cfdump var="#cfcatch#">
</cfcatch>
</cftry>
I am getting correct output when the image column has some value i.e. image, image_b,image_c, image_d,image_e, image_f are not null.
But it's giving me an error saying error executing database query when image, image_b,image_c, image_d,image_e, image_f are null.
Please suggest possible solutions.

The reason why you're getting an error message is because all of the <cfif> conditions are false, it's like executing a <cfquery> with no code inside of it. So you will need to add an additional condition outside the <cfquery> block to test and make sure at least one of your UPDATE commands will execute.
<cfquery name="getPreviousDBentries" datasource="#application.datasource#">
select image, image_b,
image_c,image_d,image_e, image_f from used_listings_v2 where id = '#edit#'
</cfquery>
<cfif NOT (len(getPreviousDBentries.image) eq 0> AND
len(getPreviousDBentries.image_b) eq 0 AND
len(getPreviousDBentries.image_c) eq 0 AND
len(getPreviousDBentries.image_d) eq 0 AND
len(getPreviousDBentries.image_e) eq 0 AND
len(getPreviousDBentries.image_f) eq 0)>
<cftry>
<cfquery name="updateToNull" datasource="#application.datasource#">
<cfif len(getPreviousDBentries.image) neq 0>
Update used_listings_v2 SET image = NULL where id = '#edit#'
</cfif>
<cfif len(getPreviousDBentries.image_b) neq 0>
Update used_listings_v2 SET image_b = NULL where id = '#edit#'
</cfif>
<cfif len(getPreviousDBentries.image_c) neq 0>
Update used_listings_v2 SET image_c = NULL where id = '#edit#'
</cfif>
<cfif len(getPreviousDBentries.image_d) neq 0>
Update used_listings_v2 SET image_d = NULL where id = '#edit#'
</cfif>
<cfif len(getPreviousDBentries.image_e) neq 0>
Update used_listings_v2 SET image_e = NULL where id = '#edit#'
</cfif>
<cfif len(getPreviousDBentries.image_f) neq 0>
Update used_listings_v2 SET image_f = NULL where id = '#edit#'
</cfif>
</cfquery>
<cfcatch>
<cfdump var="#cfcatch#">
</cfcatch>
</cftry>
</cfif>

#user12031119's answer already explains why the error occurs. As far as the code, instead of constructing multiple queries, a single query would be more maintainable. Use a CASE statement or your database's version of IIF to update the columns only if the value is empty. The exact syntax is dbms specific.
For example, say the image columns are all populated except for "image_d":
Sample
id | image | image_b | image_c | image_d
1 | arrow.png | up.png | down.png | (empty string)
DDL (SQL Server)
CREATE TABLE used_listings_v2
(
id int
, image varchar(50)
, image_b varchar(50)
, image_c varchar(50)
, image_d varchar(50)
)
;
INSERT INTO used_listings_v2 (id, image, image_b, image_c, image_d)
VALUES (1, 'arrow.png', 'up.png', 'down.png', '')
;
Use a CASE to check the length of the existing values, and set them to NULL only if the contain an empty string (i.e. length = 0).
-- Example using CASE
SET Column = CASE WHEN LEN(Column) = 0 THEN NULL ELSE Column END
-- Example using IIF
SET Column = IIF( LEN(Column) = 0, NULL, Column )
So this query will preserve any existing value and only update empty columns to null:
SQL Fiddle
UPDATE used_listings_v2
SET image = CASE WHEN LEN(image) = 0 THEN NULL ELSE image END
, image_b = CASE WHEN LEN(image_b) = 0 THEN NULL ELSE image_b END
, image_c = CASE WHEN LEN(image_c) = 0 THEN NULL ELSE image_c END
, image_d = CASE WHEN LEN(image_d) = 0 THEN NULL ELSE image_d END
WHERE id = 1
Results
id | image | image_b | image_c | image_d
1 | arrow.png | up.png | down.png | (null)
NB: In the actual cfquery, wrap the #edit# variable in cfqueryparam to help protect the query against sql injection.
Having said that though, having a bunch of similarly named columns all storing the same thing (i.e. image, image_b, image_c, .., image_N) is a strong indicator you need to normalize the model. Storing the images in rows instead of columns, provides much greater flexibility and would simplify tasks like this.

Related

check the result of a CFQUERY via CFIF statement

I am having an issue with the sytnax on how to get a value from a database and then check that value in an if statement in ColdFusion
This is what I have so far:
<cfquery name="reserveCheck" datasource="RC">
SELECT comp_type FROM partnerCompany WHERE comp_ID = "#COOKIE.RISOURCEUSRID#"
</cfquery>
<cfoutput>
<cfif #reserveCheck# NEQ 4>
<li>Product Search</li>
</cfif>
</cfoutput>
Change this:
<cfif #reserveCheck# NEQ 4>
to this
<cfif reserveCheck.comp_type NEQ 4>
This assumes your query only returns one row. If the query returns more than one row, the code in this answer only looks at the first row. That may or may not be what you want.
You could modify your query so that it is not selected in the first place. Change your query to
<cfquery name="reserveCheck" datasource="RC">
SELECT comp_type FROM partnerCompany
WHERE comp_ID = "#COOKIE.RISOURCEUSRID#"
AND comp_type <> 4
</cfquery>

How to compare a string from a query results?

I want to get the total number of records that a column has for a string.
For example, seller column = 'ONA'. I want to know how many records are equal to "ONA" and how many are not.
This is what I have:
<cfset stringONA= "ONA">
<CFSET onaseller= 0>
<CFSET notseller=0>
<cfloop query="getunion_again">
<cfif #getunion_again.seller# eq stringONA>
<cfset onaseller = onaseller +1 >
<P>TEST</P>
<cfelse>
<cfset notseller = notseller +1>
</cfif>
</cfloop>
<cfdump var=#onaseller #>
<cfdump var=#notseller #>
I'm not getting any errors, just not getting any count.
Wouldn't it just be easier to do a query-of-query to get the number of records that match your criteria without looping?
<cfquery name="qryCount" dbtype="query">
SELECT COUNT(*) AS positive_count
FROM getunion_again
WHERE seller = <cfqueryparam cfsqltype="cf_sql_varchar" value="#stringONA#">
</cfquery>
<cfset onaseller = qryCount.positive_count>
<cfset notseller = getunion_again.recordcount - onaseller>
One can use listValueCountNoCase() to count the matches in a list, and one can use valueList() to extract a query column as a list. And the number of mismatches is the number of rows less the number of matches.
So:
values = valueList(getunion_again.seller);
onaseller = listValueCountNoCase(values, stringONA);
notseller = getunion_again.recordCount - onaseller;

identifying the coldfusion value comng to run against query

I am passing dynamically named parameters in the url. (The number of sSearch parameters can go beyond 5 to 7 or 8 etc)
sSearch_0
sSearch_1
sSearch_2
sSearch_3
sSearch_4
sSearch_5
I want to run a loop to do a search within a query. I am trying like this:
<cfloop from="0" to="5" index="k">
<cfset counter = k>
<cfif IsDefined('url.sSearch_' & counter)>
<cfset "check_" & k = 'url.sSearch_' & counter>
</cfif>
</cfloop>
I am trying to write in a query like this:
<cfquery datasource="#coldfusionDatasource#" name="qFiltered">
SELECT *
FROM mytable
<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>
</cfquery>
But it is not working. The error says check_ is undefined.
For dynamic variable naming using quotes, try:
<cfset "check_#k#" = 'url.sSearch_' & counter>
See this article

Why isn't my mysql query seeing this one combination of two variables but sees the rest?

I wrote a script that takes date entries and for some reason whenever I specify just a starting date with a blank end date the query never picks it up. Here's what I wrote.
<cfquery name="stec_mysql_loan_tracking_qry" result="meta_tracking" datasource="STLinux1MySQL">
Select
tslo.created,
tslo.created_by,
tslo.last_modified,
tslo.last_modified_by,
tslo.active,
tslo.is_manager,
tslo.pick_userid,
tslo.customer_code,
tslo.name,
tst.user_ip as ip,
tsl.loan_identifier,
tst.command,
tsl.tax_search_loan_id as id
From
tax_search_loan_officers tslo Left Join
tax_search_loans tsl On tsl.tax_search_loan_officer_id =
tslo.tax_search_loan_officer_id Left Join
tax_search_track tst On tst.pick_userid = tslo.pick_userid
Where
tslo.customer_code In (<cfqueryparam value="#tw_custcodes#" cfsqltype="cf_sql_varchar" list="yes">)
<cfif IsDefined('url.active')>
<cfif url.active neq "">
AND
tslo.active = <cfqueryparam value="#Trim(url.active)#" cfsqltype="cf_sql_varchar" list="yes">
</cfif>
</cfif>
<cfif IsDefined('url.is_managed')>
<cfif url.is_managed neq "">
AND
tslo.is_manager = <cfqueryparam value="#Trim(url.is_managed)#" cfsqltype="cf_sql_varchar" list="yes">
</cfif>
</cfif>
<cfif IsDefined('url.start_end')>
<cfif url.start_date neq "" and url.end_date eq "">
AND
<cfqueryparam value="#Trim(url.start_date)#" cfsqltype="cf_sql_date"> <= DATE_FORMAT(tslo.last_modified, '%Y-%m-%d')
AND
DATE_FORMAT(tslo.last_modified, '%Y-%m-%d') <= DATE_FORMAT(NOW(), '%Y-%m-%d')
</cfif>
</cfif>
<cfif IsDefined('url.start_date')>
<cfif url.end_date neq "" and url.start_date eq "">
AND
'2012-01-01' <= DATE_FORMAT(tslo.last_modified, '%Y-%m-%d')
AND
DATE_FORMAT(tslo.last_modified, '%Y-%m-%d') <= <cfqueryparam value="#Trim(url.end_date)#" cfsqltype="cf_sql_date">
</cfif>
</cfif>
<cfif isDefined('url.start_date')>
<cfif (url.start_date neq "") and (url.end_date neq "")>
AND
<cfqueryparam value="#Trim(url.start_date)#" cfsqltype="cf_sql_date"> <= DATE_FORMAT(tslo.last_modified, '%Y-%m-%d')
AND
DATE_FORMAT(tslo.last_modified, '%Y-%m-%d') <= <cfqueryparam value="#Trim(url.end_date)#" cfsqltype="cf_sql_date">
</cfif>
</cfif>
</cfquery>
And here is what it sees if url.end_date = "" but url.start_date = a value:
Select
tslo.created,
tslo.created_by,
tslo.last_modified,
tslo.last_modified_by,
tslo.active,
tslo.is_manager,
tslo.pick_userid,
tslo.customer_code,
tslo.name,
tst.user_ip as ip,
tsl.loan_identifier,
tst.command,
tsl.tax_search_loan_id as id
From
tax_search_loan_officers tslo Left Join
tax_search_loans tsl On tsl.tax_search_loan_officer_id =
tslo.tax_search_loan_officer_id Left Join
tax_search_track tst On tst.pick_userid = tslo.pick_userid
Where
tslo.customer_code In (?)
However, every other combination is fine. I've tried rewriting the cfif blocks but this structure is the only one that gets 2/3 while the rest fail.
(From the comments ..)
<cfif IsDefined('url.start_end')>
It looks like you have three date variables: url.start_date, url.end_date and url.start_end. What is url.start_end - is it a typo?
As an aside, you might want to set defaults values for the variables so you could eliminate some of the cfif conditions. Then work on simplifying the rest of the logic, because it seems more complex than is necessary ... Dan's response contains some good suggestions. I strongly suspect you could simplify the code and make the query more efficient to boot by getting rid of the DATE_FORMAT(ColumnName, '%Y-%m-%d') statements, because they will prevent the database from properly utilizing indexes on the referenced column.
Update:
After taking a closer look, I think this is what the code is trying to accomplish:
If both dates are present, filter on the given values
If only one of the dates is present, apply a default for the missing date. Then filter on both values.
If neither date is present, skip the filtering.
Something along these lines should mimic the behavior of current code. Note, it uses this type of comparison as a more index-friendly way of handling "time" issues:
WHERE column >= {startDateAtMidnight}
AND column < {dayAfterEndDateAtMidnight}
Example:
<!--- default both to something that is NOT a valid date --->
<cfparam name="url.start_date" default="">
<cfparam name="url.end_date" default="">
<!---
If at least ONE of the dates was supplied, apply
the desired defaults for missing values
--->
<cfif isDate(url.start_date) || isDate(url.end_date)>
<cfset url.start_date = isDate(url.start_date) ? url.start_date : "some default like 2012-01-01 here">
<cfset url.end_date = isDate(url.end_date) ? url.end_date : now()>
</cfif>
<cfquery ....>
SELECT ...
FROM ...
WHERE ...
<!--- apply the filter when both dates are populated. --->
<cfif isDate(url.start_date) and isDate(url.end_date)>
AND tslo.last_modified >= <cfqueryparam value="#url.start_date#" cfsqltype="cf_sql_date">
AND tslo.last_modified < <cfqueryparam value="#dateAdd('d', 1, url.end_date)#" cfsqltype="cf_sql_date">
</cfif>
</cfquery>
It might not be the cause, but you are mixing data types. This:
and <cfqueryparam value="#Trim(url.start_date)#" cfsqltype="cf_sql_date">
<= DATE_FORMAT(tslo.last_modified, '%Y-%m-%d')
will have a date on the left hand side of your comparison operator and a string on the right. Even if it runs without error, you might get unexpected results. As a minimum, remove the date_format function from the right hand side.
Then we have this:
AND DATE_FORMAT(tslo.last_modified, '%Y-%m-%d') <= DATE_FORMAT(NOW(), '%Y-%m-%d')
at least it's comparing a string to a string, but it's inefficient. In the overall scheme of things, maybe you want something like this:
and tslo.last_modified >=
<cfqueryparam value="#Trim(url.start_date)#" cfsqltype="cf_sql_date">
and tslo.last_modified =< now()

Store id values in cookie with coldfusion

Looking for a way to track the last 5 product ids in a cookie via coldfusion. I'll set a new id each time a product page is visited. The product ids could be stored in a comma separate list. How would I store only the last 5 product ids?
You could try something like this (untested):
<cfset thisproductid = id_you_somehow_know_from_this_page>
<cfif not structkeyexists( cookie, 'mylist' )>
<!--- no cookie? make one and set it to this ID --->
<cfcookie name="mylist" value="#thisproductid#">
<cfelse>
<cfif listlen( cookie.mylist ) eq 5>
<!--- lifo --->
<cfset cookie.mylist = listdeleteat( cookie.mylist, 1 )>
<cfelse>
<!--- check for odd conditions like listlen gt 5? up to you --->
</cfif>
<cfset cookie.mylist = listappend( cookie.mylist, thisproductid )>
</cfif>