CF two tables have one idea match Name from the other - coldfusion

I am trying to combine two tables in the first table (dbo.Dealer_Track_Work) I have a dealerID this is ID matches the ID number for the second table (dbo.Dealer_Track_Dealers) and I am trying to have the dealerID match the Name from the second table and display instead of the number. Will someone please tell me where I might be going wrong?
<cffunction name="displayTable" access="public" returntype="query">
<cfset var processTable = ''>
<cfquery name="processTable">
SELECT *
FROM dbo.Dealer_Track_Work, dbo.Dealer_Track_Dealers
WHERE dbo.Dealer_Track_Work.dealerID = dbo.Dealer_Track_Dealers.Name
</cfquery>
<cfreturn processTable>
</cffunction>
<cfoutput>#Name#</cfoutput>
Table 1
Table2

<cffunction name="displayTable" access="public" returntype="query">
<cfset var processTable = ''>
<cfquery name="processTable">
SELECT name
FROM dbo.Dealer_Track_Work, dbo.Dealer_Track_Dealers
WHERE dbo.Dealer_Track_Work.dealerID = dbo.Dealer_Track_Dealers.id
</cfquery>
<cfreturn processTable>
</cffunction>
<cfoutput>#processTable.Name#</cfoutput>
Ideally you would use the ANSI join syntax
<cffunction name="displayTable" access="public" returntype="query">
<cfset var processTable = ''>
<cfquery name="processTable">
SELECT name
FROM dbo.Dealer_Track_Work
INNER JOIN dbo.Dealer_Track_Dealers ON dbo.Dealer_Track_Work.dealerID = dbo.Dealer_Track_Dealers.id
</cfquery>
<cfreturn processTable>
</cffunction>
<cfoutput>#processTable.Name#</cfoutput>

Related

Can I return columns in text form from a function with sql query in coldfusion

I want to write a function in CF, that has a query that returns multiple columns. I researched and read and could only find examples of functions with sql queries only returning the table view of the struct.
How would I write a function in CF with sql queries and output each column in text format
I been googling it and looking on tutorial websites, with no luck
<cffunction name="queryListEmployee" returntype="query" output="false">
<cfargument name="EMPID" type="numeric" default="1"/>
<cfset var listEmployee = ""/>
<cfquery name="local.listContractors" datasource="DB">
SELECT E.FIRSTNAME, E.LASTNAME
FROM EMPLOYEE E
WHERE E.ID = <cfqueryparam value="#arguments.EMPID#" cfsqltype="cf_sql_decimal" scale="0"/>
</cfquery>
<cfreturn local.listEmployee/>
I want to be able to output column names like queryListEmployee.firstname and queryListEmployee.lastname
You've got the idea right. Just a few tweaks:
<cffunction name="getEmployeeByID" returntype="query" output="false">
<cfargument name="EMPID" type="numeric" default="1"/>
<cfquery name="local.employee" datasource="DB">
SELECT E.FIRSTNAME, E.LASTNAME
FROM EMPLOYEE E
WHERE E.ID = <cfqueryparam
value="#arguments.EMPID#"
cfsqltype="cf_sql_integer"/>
</cfquery>
<cfreturn local.employee/>
</cffunction>
Then call this function like so:
<cfset qEmployee = getEmployeeByID(1)>
and output the data like this:
<cfoutput query="qEmployee">
<li>#qEmployee.FIRSTNAME# #qEmployee.LASTNAME#</li>
</cfoutput>
This function will only ever return one record. You can search and figure out how to dynamically adjust the search criteria in order to return multiple records.
You might check out http://www.learncfinaweek.com/ to get learn more of the basics of ColdFusion.

How to join two queries from different databases without qoq?

I have two different queries
<cfquery datasource="#one#" name="GetResults">
SELECT ID, Account, Value
FROM Logger_Events
left join Event_Details
on ID = EventID
where type = '123'
</cfquery>
<cfquery datasource="#two#" name="getSubtotal">
select account from daily
</cfquery>
The first query gives me like 200 records , the second query gives me like
half a million records.
Is there a way i can make the second query get the records from the first query,
without making a query of queries?
I would be using the account column to join.
The tables are in different servers.
This is one of the reasons for a QoQ. You could run the 1st query, then convert the data to XML and pass it as a parameter to a stored proc on the 2nd DB server in order to filter the 2nd query directly on the DB. Just join to the XML or use the XML to populate a temp table.
Since you are using sql server, I suggest linked servers. Pick one of your servers and set up a linked server to the other one. Then set up a stored procedure that does something like this;
declare #TempTable table (field1 datatype1, etc);
insert into #TempTable (field1, field2, etc)
select field1, field2, etc
from openquery
(linkedServerName,
'select field1, field2 etc
from blah blah blah
')
select yourfields
from #TempTable join aTableInThatDB on etc
The details are kind of painful at first, but it works very well. Also, there is lot's of information regarding linked servers and openquery on the internet.
I have done this function to Replace the foreign key of a table for a text field contained in the foreign table. This could instead append new columns to the original query with QueryAddColumn() and QuerySetCell().
The idea is to convert one of the queries into a struct.
My function is pretty basic but at the moment looks something like this:
<cffunction name="joinNameFromIDStructs" returnType="query" hint="Returns the Fund Activity">
<cfargument name="qryMain" type="query" required="Yes" hint='The query which is going to be translated' >
<cfargument name="foreignTable" type="string" required="Yes" hint='table which contains the details of our foreign column' >
<cfargument name="foreignPK" type="string" required="No" default="#arguments.foreignTable#ID" hint="Primary Key in the foreign table" >
<cfargument name="foreignKey" type="string" required="Yes" hint="column in the main table which references another table" >
<cfargument name="foreignText" type="string" required="Yes" hint="the column in the foreing table which hold the required details. It will override the foreign key column in the main table" >
<cfset var idPK = "">
<cfset var qryForeignTable = "">
<cfset var stForeignTable = StructNew()>
<cfset var listForeignPKs = evaluate("ValueList(arguments.qryMain.#arguments.foreignKey#)")/>
<cfif ListLen(listForeignPKs)>
<cfquery name="qryForeignTable" datasource='#application.siteDataSource#' >
SELECT #arguments.foreignPK#, #arguments.foreignText# FROM #arguments.foreignTable#
WHERE #arguments.foreignPK# IN (<cfqueryparam cfsqltype="cf_sql_integer" value='#arrayToList(listToArray(listForeignPKs))#' list="true" />) <!--- CF8 does not support ListRemoveDuplicates , hence we will use the array conversion to remove empties --->
</cfquery>
<cfloop query='qryForeignTable'>
<cfset stForeignTable[qryForeignTable[arguments.foreignPK][qryForeignTable.currentrow]] = qryForeignTable[arguments.foreignText][qryForeignTable.currentrow]/>
</cfloop>
<cfloop query='arguments.qryMain'>
<cfset idPK = arguments.qryMain[arguments.foreignKey]/>
<cfif idPK neq "">
<cfset arguments.qryMain[arguments.foreignKey][arguments.qryMain.currentrow] = stForeignTable[idPK]/>
</cfif>
</cfloop>
</cfif>
<cfreturn arguments.qryMain/>
</cffunction>

Coldfusion OutOfMemoryError (CF9/Wheels)

I have a function which loops over a query and updates a database row for each item. After about 7000 iterations it's throwing an out of memory error - Java heap space.
Is there anything obviously wrong with this code ?
<cfloop query=loc.fixItems>
<cfset loc.count = loc.count + 1>
<cfset var categoryName = loc.fixItems.categoryName>
<cfinvoke component="Item" method="updateCode"
itemId="#loc.fixItems.itemId#" code="#loc.fixItems.newCode#"/>
<!--- Increment counter for category --->
<cfif structKeyExists(categoryMap, categoryName)>
<cfset var inc = structFind(categoryMap, categoryName) + 1>
<cfset structUpdate(categoryMap, categoryName, inc)>
<cfelse>
<cfset structInsert(categoryMap, categoryName, 1)>
</cfif>
</cfloop>
and in the update component:
<cffunction name="updateCode">
<cfargument name="itemId" type="numeric" required="yes">
<cfargument name="code" type="string" required="yes">
<cfset var loc = {}>
<cfquery name="loc.update">
update items
set code = <cfqueryparam value="#code#">
where id = <cfqueryparam value="#itemId#">
</cfquery>
</cffunction>
Don't use cfinvoke to create your Item component every iteration of your fixItems query. Create it once before that using createObject and simply call the updateCode method each time directly on the object.
The following can be done:
Change your <cfqueryparam> to use the appropriate cf_sql type. Are code and id really strings?
Don't give your <cfquery> a name. You are not keeping the result anyway. var loc doesn't help either
Bump up you memory to the JVM Addtional approach Use Java 7 and G1GC
Every 100 to 1000 iterations do a forced Garbage Collect
Update your data in bulk. XML based table variables can do this.
Make your function silent
Consider ORM on this

how to determine the rollback cause in a cftransaction

I have set of inserts that are wrapped in a <cftransaction> block, and I am getting a error and the insert is being rolled back.
Here is the code in question stubbed for space:
<cffunction name="InsertTCUV" access="public">
<cfargument name="vehicle required="true" type="xml" />
//Parsing the xml document here
<cftransaction>
<cfquery name="TCUVinsert datasource="mydb">
INSERT INTO tcuv
VALUES(...)
<cfquery>
<cfquery name="qLatestTCUVID" datasource="mydb">
SELECT TOP 1 tcuv_id FROM dbo.tcuv ORDER BY tcuv_id DESC
</cfquery>
<cfset curTCUVID = qLatestTCUVID.tcuv_ID>
<cfset optionsResult = insertOptions(curTCUVID,vehicle>
<cfset imagesResult = insertImages(curTCUVID,vehicle)>
<cfset standardFeaturesResult = insertStandardFeatures(curTCUVID,vehicle
</cftransaction>
</cffunction>
<cffunction name="insertOptions" access="private">
<cfargument name="TCUVID required="true type="numeric" />
<cfargument name="vehicleInfo" required="true" type="xml" />
<cfset var result = "good">
<cftry>
<cfset optionNode = xmlSearch(arguments.vehicleInfo[1], "p:RemarketingOption">
<cfloop index="i" from="1" to="#arrayLen(optionNode)#">
<cfset optionNodeNotes = XmlSearch(optionNode[#i#], "p:OptionNotes")>
<cfset optionNotes = "">
<cfloop index="j" from="1" to="#ArrayLen(optionNotesNodes)#">
<cfoutput>
<cfset optionNotes = optionNotes & " " & #optionNotesNodes[j].xmlText#>
</cfoutput>
</cfloop>
<cfquery name="insertOptions" datasource="mydb">
INSERT INTO dbo.tcuv_options
VALUES (
<cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.TCUVID#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value='#xmlSearch(optionNode[i], "p:OptionID")[1].xmlText#'>,
<cfqueryparam cfsqltype="cf_sql_varchar" value='#xmlSearch(optionNode[i], "p:OptionTypeCode")[1].xmlText#'>,
<cfqueryparam cfsqltype="cf_sql_varchar" value='#xmlSearch(optionNode[i], "p:OptionShortDescription")[1].xmlText#'>,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#optionNotes#">
)
</cfquery>
</cfloop>
<cfcatch type="database">
//dumping cfcatch.* information
<cfset result = "error"
</cfcatch>
</cftry>
<cfreturn result>
</cffunction>
This whole thing is in a loop on the calling page, and everything works fine the first time through the loop. One the second pass, the TCUVInsert works, but I get to the insertOptions function, a coldfusion error is thrown saying that, variable insertOptions is undefined, and when I get the database, the second row isn't there, which tells me there was an error and the insert rolled back. So, there is an error with the insert of the options, and coldfusion isn't giving me the right error to diagnose it. So either I have to look in the database logs, which apparently are not setup, or try to extract the error from the cftransaction block, which I'm not sure how to do.
coldfusion 9, sql server 2008 r2
Any thoughts?
<cffunction name="insertOptions" access="private">
You are overwriting the function by using the same name for a query variable:
<cfquery name="insertOptions" datasource="imports">
Interestingly it is all because the query name was not var scoped. Functions are stored in the variables scope of the component. So by failing to localize the query name, you end up overwriting the function stored in variables.insertOptions when you run the query. Because insert statements do not return a resultset, that variable ends up being undefined. Hence the error. In this case the solution is to either scope the query name, or better yet remove it entirely (since it is not populated anyway).
Just one more reason to always var/local scope function variables - yes, query names too!

Strange database error in Coldfusion

I have two queries:
<cfquery name="getChairReview" datasource="#application.dsn#">
SELECT*
FROM eval_reviews
WHERE faculty = <cfqueryparam cfsqltype="cf_sql_numeric" value="#HTMLEditFormat(trim(arguments.id))#">
AND evalYear = <cfqueryparam cfsqltype="cf_sql_numeric" value="#HTMLEditFormat(trim(arguments.evalYear))#">
AND levels = <cfqueryparam cfsqltype="cf_sql_varchar" value="chair">
</cfquery>
<cfreturn getChairReview>
</cffunction>
<cffunction name="getDeanReview" access="public" returntype="query">
<cfargument name="id" type="numeric" required="yes">
<cfargument name="evalYear" type="numeric" required="yes">
<cfset var getDeanReview = QueryNew("")>
<cfquery name="getDeanReview" datasource="#application.dsn#">
SELECT*
FROM eval_reviews
WHERE faculty = <cfqueryparam cfsqltype="cf_sql_numeric" value="#HTMLEditFormat(trim(arguments.id))#">
AND evalYear = <cfqueryparam cfsqltype="cf_sql_numeric" value="#HTMLEditFormat(trim(arguments.evalYear))#">
AND levels = 'dean'
</cfquery>
<cfreturn getDeanReview>
</cffunction>
Both of them work fine when evalYear is 2012. If I send in 2011 I get an error on getDeanReview that states: [Macromedia][SQLServer JDBC Driver][SQLServer]Error converting data type varchar to numeric
The line it gives this error on is the AND levels = 'dean' (note: I had taken out the cfqueryparam tag to make sure I didn't goof that up.)
I find this strange because these two queries are almost identical except one has chair as a param and the other dean. (Yes, I could have had one function to do the job...with extra param for level)
I changed 'dean' to 'chair' with evalYear still 2011...guess what? It worked. This is quite odd...
levels is a varchar field.
Any ideas?
That's weird.
Okay, for grits & shins, try making the second query:
and levels like '%dean%'
Also, try it the way you have it, but remove the line about year and let it select everything regardless of year... see what your output looks like.
Lastly.. I don't think you need to worry about HTMLEditFormat in your value params in cfqueryparam.
Rob