ColdFusion Executing Queries Parallel (Data not updating) - coldfusion

I do an update and then I try to get back the updated value of the field of which was updated. The issue however, is I am not getting the updated value, rather the prior value. I know the update works correctly because if I query it shows the returned data. I have tried cftransaction isolation="serializable" but it does not work.
My code is below, is there a way around this or will I have to make 2 AJAX request for simpe issue?
<cfquery datasource="#application.datasource#">
UPDATE gt_timesheet
SET
phaseid=<cfqueryparam value="#form.phase#" cfsqltype="CF_SQL_INTEGER">,
projectid=<cfqueryparam value="#form.project#" cfsqltype="CF_SQL_INTEGER">
WHERE
timesheetid=<cfqueryparam value="#form.timesheetid#" cfsqltype="CF_SQL_INTEGER">
</cfquery>
<cfquery name="phase" datasource="#application.datasource#">
SELECT status,
(
SELECT ROUND(sum(time_to_sec(duration))/3600,2)
FROM gt_timesheet
WHERE gt_timesheet.phaseid=gt_phases.phaseid
) as billedbillablehours,
(
SELECT ROUND(sum(time_to_sec(hours))/3600,2)
FROM gt_services
WHERE gt_phases.phaseid=gt_services.phaseid
) as billablehours
FROM gt_phases
WHERE phaseid=<cfqueryparam value="#form.phase#" cfsqltype="CF_SQL_INTEGER">
</cfquery>
This is making me go nuts because this language is constantly making tasks that should be simple tedious.

You don't have a CF problem, you have an SQL problem, and I think its the subqueries. First why a subquery and not a join?
Can you confirm that they are 1:1 relationships in the subqueries, because if they are one to many you are just going to get the first match.
I don't know your database schema, but doing it the way you currently are i think the SELECT needs to have the table match based on the form field you have just updated
<cfquery name="phase" datasource="#application.datasource#">
SELECT status,
(
SELECT ROUND(sum(time_to_sec(duration))/3600,2)
FROM gt_timesheet
WHERE gt_timesheet.phaseid=<cfqueryparam value="#form.phase#" cfsqltype="CF_SQL_INTEGER">
) as billedbillablehours,
(
SELECT ROUND(sum(time_to_sec(hours))/3600,2)
FROM gt_services
WHERE gt_services.phaseid=<cfqueryparam value="#form.phase#" cfsqltype="CF_SQL_INTEGER">
) as billablehours
FROM gt_phases
WHERE phaseid=<cfqueryparam value="#form.phase#" cfsqltype="CF_SQL_INTEGER">
</cfquery>
Hope that gets you somewhere, if not I think you need to explain the database schema more.

ColdFusion does not execute anything in the same request in Parallel unless you use <cfthread>

How is the duration updated after you run the first Update statement? Does it call a trigger? Possibly that is causing the update of the "duration" field to run after the second query. You could try adding a 1 second sleep after the first query to make sure the second query gets the correct value.

I guess you are missing something in the update statement. Why don't you re-evaluate the query's once again.

Related

Issue with ColdFusion Query of Query after upgrading ColdFusion server from CF9 to CF21

I cannot figure this out. My company recently upgraded our ColdFusion Server from CF9 to CF2021. One of my pages uses queries of queries to run. Prior to the upgrade the page worked fine. However after the upgrade the query of query where statement is not returning any results. Even though the original query has the data. The data is coming from DB2 data source in case that changed with the new version.
<cfquery name = "query_data_sample" dbtype="query">
SELECT
SAMPLE_DATE
, SAMPLE_NBR
, SAMPLE_MISC_NBR
, SUM (RECD_QTY) AS TTL_RECD_QTY
, SUM (MISC_QTY_1) AS TTL_MISC_QTY_1
, SUM ( 1 ) AS TTL_COUNT
FROM original_query_result
WHERE 1=1
AND SAMPLE_DATE = <cfqueryparam value = "#original_query_result.SAMPLE_DATE#" cfsqltype = "CF_SQL_DATE">
AND SAMPLE_NBR = <cfqueryparam value = "#trim(original_query_result.SAMPLE_NBR)#" cfsqltype = "CF_SQL_CHAR">
AND SAMPLE_MISC_NBR = <cfqueryparam value = "#trim(original_query_result.SAMPLE_MISC_NBR)#" cfsqltype = "CF_SQL_CHAR">
GROUP BY
SAMPLE_DATE
, SAMPLE_NBR
, SAMPLE_MISC_NBR
</cfquery>
When I comment out the AND statements and dump out the above query I can see the output of the original_query_result with all the TTL values and Sample rows. However if I want to grab just one row with the AND statements then the query comes back as not finding the row. I am doing a cfoutput query = original_query_result and trying to get the total quantity to display on each row in my output grid table.
Any help would be greatly appreciated. I have been trying to figure this out for more then a week now.
I saw something similar a while back and found this post:
https://web.archive.org/web/20180210052449/http://blog.dkferguson.com/index.cfm/2010/2/17/Using-Querie-of-Queries-with-CFDirectory
Basically I had to CAST the date and use cfqueryparam (as you are):
SAMPLE_DATE = CAST(<cfqueryparam value="#original_query_result.SAMPLE_DATE#" cfsqltype="CF_SQL_DATE"> AS date)
The post said they had to cast both sides but I didn't find this.

Why doesn't Lucee consider column alias name in QoQ

I was comparing the following queries in my local CF & Lucee servers. The ColdFusion server throws a QoQ runtime error. However, when I execute the same queries in Lucee, it returns the needed query results.
<cfquery name="getusers" datasource="myDSN">
SELECT
UC.UserContactName, U.UserID
FROM Users U
INNER JOIN UserContacts UC ON U.UserID = UC.UserID
WHERE U.UserID in (99,52,41,76,15)
</cfquery>
<cfquery name="getContactName" dbtype="query">
SELECT UserContactName FROM getusers
WHERE U.UserID = <cfqueryparam value="76" cfsqltype="cf_sql_integer">
</cfquery>
<cfdump var="#getContactName#" />
The CF server throws this error on the above code, because it considers the alias name:
The selected column reference U.UserID does not match any table in the
FROM table list.
However, the Lucee server doesn't consider the alias name, ran runs the above without error. Does anyone know why the Lucee server does not consider the QoQ column alias name? Please share your thoughts or suggestions about this.
The getusers query results in the columns:
UserContactName | UserID
A QoQ on getusers no longer has any table related information stored. If you reference U (as in U.UserID), ACF expects a (new) reference in the QoQ to be able to resolve what U even means.
Lucee on the other hand stores these information and can resolve it using an alias. You can check the source code how it parses the QoQ statement.
Regardless of the capabilities of Lucee, I suggest to remove former aliases in QoQ statements. Consider debugging a QoQ statement when your query dump doesn't even hint you about stored aliases.

PreparedStatement.setNString(int,java.lang.String) error trying to use Query of Queries

I have a simple Query of Queries statement like this:
<cfquery name="rsProductTypeID" dbtype="query">
SELECT
ProductTypeID
FROM
rsProductTypes
WHERE
ProductType = <cfqueryparam value="Computers" cfsqltype="cf_sql_nvarchar"/>;
</cfquery>
All it is doing is asking for the primary key value (ProductTypeID) from the recordset rsProductType depending on which ProductType we are asking for.
For some reason the above query gives me this error:
PreparedStatement.setNString(int,java.lang.String)
But if I change the Query of Queries and remove the <cfqueryparam> part and replace it with normal text, then it works fine. Here is the working code:
<cfquery name="rsProductTypeID" dbtype="query">
SELECT
ProductTypeID
FROM
rsProductTypes
WHERE
ProductType = 'Computers';
</cfquery>
I can't tell what the difference is between the code that is causing it to fail when using <cfqueryparam> and not.
I think I figured it out... when ColdFusion returns a recordset, it doesn't maintain the original datatype from the database. In my database ProductType is defined as nvarchar(50) but ColdFusion returns it as varchar format. So the cfsqltype attribute was causing the error. I changed the cfsqltype attribute to cf_sql_varchar and it works fine. Very annoying but what can you do.
I posted it as a self-answer in case anyone else gets this error. Not sure if that's against the rules or not.
cf_sql_nvarchar is not a valid value for the cfsqltype attribute of cfqueryparam
Docs: https://wikidocs.adobe.com/wiki/display/coldfusionen/cfqueryparam

CFDump of query column does not display all values

The dumping results for the following QoQ are perfectly fine:
<cfquery datasource = "XX.XX.X.XX" name="master2">
SELECT DATE(Timedetail) as FIRSTCONN
, count(Timedetail) as FIRSTOccurances
, EVENTS
FROM MyDatabase
WHERE EVENTS = "FIRST" GROUP BY FIRSTCONN
<!--- LIMIT 0,10 --->;
</cfquery>
<cfdump var="#master2#">
<cfquery dbtype="query" name="detail2">
SELECT *
FROM master2
WHERE FIRSTCONN >= <cfqueryparam value="#startdate#" cfsqltype="cf_sql_date">
AND FIRSTCONN < <cfqueryparam value="#enddate#" cfsqltype="cf_sql_date">;
</cfquery>
Dumping Result: <cfdump var="#detail2#"><cfabort>
However, when I try to use the following check on the QoQ:
Dumping Result: <cfdump var="#detail2.FIRSTCONN#"><cfabort>
I don't see the full list of FIRSTCONN values. Instead I just see one line:
Dumping Result: {ts '2013-06-29 00:00:00'}
Ideally I should see the list of all the FIRSTCONN in my browser, shouldn't I?
You are looking at the default behaviour of coldfusion. When you output or dump queryname.fieldname, and don't specify a row number, you get the value from the first row. If you want to see all the rows, your choices are:
Look at the value list
Output/dump the entire query
Do another q of q for just that column and cfdump it.
Use cfoutput with a query attribute and just output that field
If you are looking to produce the same structured output that cfdump produces when dumping a query, I have two suggestions:
My First Inclination:
<cfdump var="#ListToArray(ValueList(queryName.columnName))#" />
That one is obviously a, very, minor continuation on Dan's suggestion.
The second is available for CF 8+ and it is
Exactly What You Wanted:
<cfdump var="#queryName#" show="columnName"/>
You may specify either columns to display in the output via the show attributes or you can hide specific columns by assigning a value to the hide attribute.
CFAbort in CF Docs
Granted, this post is almost 18 months old but maybe this will help someone that stumbles onto this page.
This is a little off topic, but I'd like to point out that in my instance of CF2016 the cfdump function suppresses the output of columns (and makes them appear empty) that have lots of text in them (or have the option to have lots of text). I'm not sure if it's the nVarChar(max) setting of the table field or what, but in order to see the content of these big fields, I actually have to make a separate query that selects only this one field, and use a separate cfdump in order to see its contents. This is only for debugging purposes, but it will keep you from going crazy and rewriting your update and insert statements over and over (because they appear to not be working all the way)...

CF QoQ is throwing runtime error. "Column reference is not a column in any of the tables of the FROM table list."

In my code, I first create the Query Object:
<cfset memberData = QueryNew('slug,pos,firstname,lastname,email') />
<cfset temp = QueryAddRow(memberData, #numMembers#) />
<!--- LOOP POPULATES QUERY OBJECT --->
<cfloop...</cfloop>
I can then verify that it has been populated by running the following (which outputs as expected):
<cfoutput query="memberData">
#slug# - #pos#<br>
</cfoutput>
I then try to query the memberData Query Object and all hell breaks loose. If I run:
<cfquery name="members" dbtype="query">
SELECT slug,pos,firstname,lastname
FROM memberData
WHERE slug = #slug#
</cfquery>
I get this error:
Query Of Queries runtime error.
The select column reference [university] is not a column in any of the tables of the FROM table list.
In the output test mentioned above, I can verify that "university" is one of the values in the slug column. Clearly I'm missing something in my approach, but I'm baffled as to what it might be. Any help would be greatly appreciated!
Query Of Queries runtime error.
The select column reference
[university] is not a column in any of the tables of the FROM table
list
Your error was caused by absence of quotes in where clause and nothing else:
This expression find rows where the value in slug column equals the value in CF slug variable (String):
WHERE slug = '#slug#'
On the other hand this expression means find rows where value in the slug column equals the value contained in the column named in the CF slug variable (String):
WHERE slug = #slug#
The most likely cause of why you needed to change to SELECT * is CF query caching. So changing it back now should solve the problem. And always use <cfqueryparam .../> as suggested by "Al Everett"
Well, it's not quite answering the question asked, but it's close enough for what I needed:
<cfquery name="members" dbtype="query">
SELECT *
FROM memberData
WHERE slug = '#slug#'
</cfquery>
I had tried the wrapping #slug# in single quotes prior to posting with no success, but doing that plus changing the query to SELECT * fixed the issue. For my content, * only adds one more value retrieved, so not really a problem in slowing down the process.