So I have this query to get the results from my database tables with the columns in and out.
<cfquery name="getInfo" datasource="testing">
select in, out from test
</cfquery>
Now what I need to do is to take a static number, eg; 100, and ADD the in and SUBTRACT the out from that static number.
So this is what I tried:
<cfquery name="getInfo" datasource="testing">
select in, out from test
</cfquery>
<table>
<cfset balance = 100>
<cfloop query="getInfo">
<cfset balance = balance + in - out> <!--- THIS IS WHAT I TRIED --->
<tr>
<td>#in#</td>
<td>#out#</td>
<td>#balance#</td>
</tr>
</cfloop>
</table>
So as you can see, I did set this code <cfset balance = 100 + in - out>. Basically what I am trying to do is to get the original value of balance which is 100 and add the values of in and subtract the value of out and save it as the new balance.
However, I am getting an error saying The value '' cannot be converted to a number..
I have set the values for in and out to be float in the database.
Where am I going wrong?
You need to update your query to cover NULL conditions
<cfquery name="getInfo" datasource="testing">
select ISNULL([in], 0) AS [in], ISNULL([out], 0) AS [out]
FROM test
</cfquery>
Also I put square brackets around in and out because they look like they might be key words
Also consider doing the math on the DB, you might get better performance
Related
I have the column deletedTime in my instances table.
Now I want to check in ColdFusion if the value is null.
There is only one record to be printed out with the query.
IsNull(test) is returning the correct value,
but IsNull(searchForDeletedInstances.deletedTime) returns false but the value is in the datatable null..
<cfquery datasource="hostmanager" name="searchForDeletedInstances">
SELECT deletedTime
FROM instances
WHERE instanceId = <cfqueryparam value="#instanceId#"
cfsqltype="CF_SQL_NVARCHAR">
</cfquery>
<cfloop query="searchForDeletedInstances">
<cfset test= #deletedTime#>
</cfloop>
<cfreturn IsNull(test)>
<cfreturn IsNull(searchForDeletedInstances.deletedTime)>
I would do the test in the query.
<cfquery datasource="hostmanager" name="searchForDeletedInstances">
SELECT deletedTime
FROM instances
WHERE instanceId = <cfqueryparam value="#instanceId#" cfsqltype="CF_SQL_NVARCHAR">
AND deletedTime IS NULL
</cfquery>
<cfreturn BooleanFormat(searchForDeletedInstances.recordcount)>
ColdFusion 2018 does allow for NULL values but the server/site has to be configured to use it. This may break a lot of older code.
ColdFusion before 2018 will use an empty string for NULL values.
I would change the query to only look for NULL deletedTime records. Then use the searchForDeletedInstances.recordCount value to determine if a NULL record was found. The code would look something like this:
<cfquery datasource="hostmanager" name="searchForDeletedInstances">
SELECT deletedTime
FROM instances
WHERE instanceId = <cfqueryparam value="#instanceId#" cfsqltype="CF_SQL_NVARCHAR">
AND deletedTime IS NULL
</cfquery>
<cfset nullRecord = searchForDeletedInstances.recordCount ? true : false>
<cfreturn nullRecord>
Null values from a query come back as empty strings. Test for IsDate() instead. You can always use cfdump to show the contents of your query so you can see the data and data types returned.
I am trying to count the amount without using SQL count() code
Is there a way to extract the results including the number amount over ColdFusion?
Select test
From ......
Where .....
<Cfif not test.RecordCount>
No records found
</Cfif>
<cfoutput query="test">#amount#</cfoutput>
It should display like this
TEST CountOutput
TEST A: 22
TEST B: 32
TEST B: 1
TEST C: 23
(From comments ...)
Why can't you use SQL for this? Unless there's a valid reason you can't use COUNT, it's by far the simplest way to aggregate. You don't need to know the specific values in the database table in order to perform a COUNT. Just do:
SELECT column, count(*) AS someAlias
FROM tableName
GROUP BY column
Yes, it is possible to do the same in ColdFusion code, but again unless there's a specific reason to do so, it's more efficient to use SQL.
<cfset data = {} />
<cfset names = {} />
<cfloop query="test">
<cfif not structKeyExists(data, test.name)>
<cfset data[test.name] = 0 />
<!--- if you need to preserve original case of name --->
<cfset names[test.name] = test.name />
</cfif>
<cfset data[test.name] += 1 />
</cfloop>
<cfoutput>
<cfloop collection="#data#" item="key">
#names[key]#: #data[key]#<br />
</cfloop>
</cfloop>
To get the total count without using SQL, Use
QUERYVARIABLE.RECORDCOUNT
Based on the condition used in the SQL query it will give you the count.
FOR Example,
<cfquery name="test">
SELECT * FROM database WHERE name=testA
</cfquery>
<cfdump var="#test.RECORDCOUNT#" />
Use this within a function, call it and store the return value in a stack or an array.
I strongly recommend you use a SQL Count(). I cannot imagine why you would want to do it inside a CFLoop or CFOutput, but it is possible if you use the Group attribute, and count each row that way.
Did you know that after you execute CFQuery against your SQL server to get all those detail records, you can run a "query of queries" summarize the SQL data. This article seems to explain it:
https://www.quackit.com/coldfusion/tutorial/coldfusion_query_of_queries.cfm
I have a SQL Server query which returns two values for one MyBusinessUnit column returns two values, say:
1111
2222
in a query object called MyQuery1
Both of these values also exist in a DB2 database's MyCorpUnit column.
What I want is to select all the matching records from the DB2 table--and, no, cross database queries are NOT working.
So, here's my Query2 for DB2 database:
<cfquery name="Query2" datasource="#application.DSN#">
SELECT MyCorpUnit WHERE MyCorpUnit IN
(
<cfqueryparam value=" #Query1.MyBusinessUnit #" CFSQLType="cf_sql_varchar" />
)
</cfquery>
But Query2 only returning matching record for only one value (1111).
So some other approach is needed. I have tried to create a string but that didn't work either.
Any idea?
Thanks!
cfqueryparam has a list attribute which might help:
<cfqueryparam value = "parameter value"
CFSQLType = "parameter type"
list = "yes|no"
maxLength = "maximum parameter length"
null = "yes|no"
scale = "number of decimal places"
separator = "separator character">
AND/OR ...additional criteria of the WHERE clause...>
I've used it before but not sure if it was in a QoQ or not. :D
ref: http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7f6f.html
I am going to accept #AJ Dyka answer [Thank you!] but I have more to add to make it complete. Indeed, per his advice, I ended up using the 'LIST' attribute. A good discussion on it can be found here.
But, as you can see in the comments, I was still getting only "1111" despite using a List. And that's because of the leading spaces in my data. I ended up using a TRIM function. Here is a code snippet.
Converted the output from Query1 to a List :
<cfset ListUniqueWStreamBusinessUnit = ValueList(Query1.MyBusinessUnit )>
Then the magical code snippet!
...
WHERE trim(GMMCU) IN
(
<cfqueryparam value="#ListUniqueWStreamBusinessUnit#"
CFSQLType="cf_sql_varchar"
list="yes" />
)
I want to set static id(product) and its dynamic price, if the id's price changes it will be displayed correspondingly, that's all I want, but I don't know the variable nor the structure of the queries and outputs, I don't know how to define the specific product's price in workcube using Coldfusion, this is as far as i've gone:
And i know that the script below is wrong ^.^
<cfquery>
SELECT
PRICE_STANDART.PRICE PRICE
FROM
PRICE_STANDART
WHERE
PRICE_STANDART.PRODUCT_ID = #product_id#
</cfquery>
<cfset product_id = 612>
#TLFormat(price_standart)#
Think the following will work with your example:
<cfset product_id = 612>
<cfquery name="price_standart" datasource="#variableNameWithDatasourceName#">
SELECT
PRICE_STANDART.PRICE PRICE
FROM
PRICE_STANDART
WHERE
PRICE_STANDART.PRODUCT_ID =
<cfqueryparam value="#product_id#" cfsqltype="cf_sql_integer">
</cfquery>
<cfoutput>#LSCurrencyFormat(price_standart.price, "international")#</cfoutput>
cfqueryparam, while not necessary, prevents SQL injection attacks and serves as a bind variable with the JDBC driver.
LSCurrenyFormat will format a numeric value as currency. TLFormat() is a not a built-in ColdFusion function.
In Coldfusion, I'm using a cfc that binds one select box to another (basically, choose a State from one box, the second box is populated with County names.) The value for the County box is a 5-digit number WHICH IS FORMATTED AS TEXT (ie. the value comes from a text field.)
The problem is that I'm finding that if the value of the selected county id starts with a '0', it's been cut off.
So I get stuff like:
ID County
11223 A
2300 B (should be 02300)
Can someone help make sure that leading 0s are not cut off?
Here's the select boxes on the page:
<!--- State Name options --->
<b>State:</b><br />
<cfselect bind="cfc:states.getStates()" bindonload="true" name="search_state" id="search_state" value="StateUSAbb" display="StateName">
</cfselect><br />
<!--- County Name options --->
<b>County:</b><br />
<cfselect bind="cfc:states.getCounties({search_state})" name="search_county" id="search_county" value="FIPS_County" display="CountyName">
</cfselect>
I hate pasting the whole .cfc but pay attention to the latter part, particularly the cfloop which uses a cfset to populate array RESULT:
<cfcomponent output="false">
<!--- Get array of media types --->
<cffunction name="getStates" access="remote" returnType="array">
<!--- Define variables --->
<cfset var data="">
<cfset var result=ArrayNew(2)>
<cfset var i=0>
<!--- Get data --->
<cfquery name="data" datasource="bridges">
SELECT DISTINCT tblLoc.StateUSAbb, lkuState.StateName
FROM lkuState INNER JOIN tblLoc ON lkuState.FIPS_State = tblLoc.FIPS_State
WHERE (lkuState.StateName <> 'New Brunswick')
UNION
SELECT '' AS StateUSAbb, ' ALL' AS StateName
FROM lkuState
ORDER BY StateName
</cfquery>
<!--- Convert results to array --->
<cfloop index="i" from="1" to="#data.RecordCount#">
<cfset result[i][1]=data.StateUSAbb[i]>
<cfset result[i][2]=data.StateName[i]>
</cfloop>
<!--- And return it --->
<cfreturn result>
</cffunction>
<!--- Get counties by state --->
<cffunction name="getCounties" access="remote" returnType="array">
<cfargument name="stateabb" type="string" required="true">
<!--- Define variables --->
<cfset var data="">
<cfset var result=ArrayNew(2)>
<cfset var i=0>
<!--- Get data --->
<cfquery name="data" datasource="bridges">
SELECT '' AS FIPS_COUNTY, ' ALL' as CountyName
FROM lkuCnty
UNION
SELECT FIPS_County, CountyName
FROM lkuCnty
WHERE StateAbb = '#ARGUMENTS.stateabb#'
ORDER BY CountyName
</cfquery>
<!--- Convert results to array --->
<cfloop index="i" from="1" to="#data.RecordCount#">
<cfset result[i][1]=data.FIPS_County[i]>
<cfset result[i][2]=data.CountyName[i]>
</cfloop>
<!--- And return it --->
<cfreturn result>
</cffunction>
</cfcomponent>
If the data is a fixed length you can use NumberFormat to force leading zero's. In general, CF is typeless so there must be some underlying conversion happening that is causing the data to get corrupt. You might try forcing the value toString(), or to debug add something like a single quote as the first character in the column value (eg. SELECT '''' + FIPS_County, '''' + CountyName FROM lkuCnty) to see if they keep all their characters.
[Update]
Based on your comments about how SQL is not returning 5 char, use this updated query to go from INT to VARCHAR with leading zeros.
SELECT DISTINCT
RIGHT('00000' + CONVERT(VARCHAR(5),StateUSAbb),5),
lkuState.StateName
FROM lkuState INNER JOIN tblLoc ON lkuState.FIPS_State = tblLoc.FIPS_State
WHERE (lkuState.StateName <> 'New Brunswick')
UNION
SELECT '' AS StateUSAbb,
' ALL' AS StateName
FROM lkuState
ORDER BY StateName
append a space to the end of the number, then CF will treat it as a string and no leading 0 will be chopped.
simple workaround: <cfset result[i][1]=data.StateUSAbb[i] & " ">
btw, you know that query object is supported for populating cfselect right? So you don't even need the loop. You can do the same workaround but in SQL inside your cfquery
UPDATE: anyway, the idea is that if u want to preserve the leading 0 and keep using CF's built in serializeJSON() or calling the cfc remote method in JSON style (which will internally invoke serializeJSON(), you can append a space so CF will treat it as a string and leading 0 will be preserved. If your script somehow must need "012345" with no trailing space, then look for another JSON seralizer from riaforge or cflib.
You're sure the data returned from your query is a text string which contains the leading zero, rather than just the integer value? Regardless, I think Zachary's suggestion of NumberFormat(x, "00000") is the way to go.