I'm an "old dog" and largely self-taught on this stuff and can usually make things work (primative and convoluted as it might be), but this is the first thing that has me really stymied.
I didn't want to burden everyone with a lot of stuff to try to explain, but, here is perhaps a better explanation and example:
(#Leigh - and thank you for your time and help!) - The query is dynamic because what I desire to have is a single "universal" page combination (form page plus accompanying action page) that is used to edit multiple different (but fairly similar) record sets (so that I don't have to write a whole bunch of individual form/action page pairs).
When this "universal" "change" form page is invoked, it is passed the "ID" variable for the particular record to be edited, along with a "listID" variable unique to the particular record set containing the record to be edited.
Using the "URL.listID", the form page then looks at a pre-defined included list of record set variables (datasource, query table, field for column 1, field for column 2, etc.) pertaining to the value of the "listID" and sets (using ) the dynamic variables. Example - if "listID" is "5", which has only one column:
<cfif #URL.listID# EQ 5>
<cfset page_title = 'Change Member Role Picklist'>
<cfset datasource = '#Session.db_docs#'>
<cfset query_tbl = 'tblMemberRole'>
<cfset columns = 1>
<cfset column1_label = 'Member Role'>
<cfset column1_field = "role">
<cfset column1_input_type = "text">
<cfset column1_input_size = "100">
<cfset column1_input_maxlength = "100">
</cfif>
The query uses those variables ("ID" plus the others it got from the above list) to retrieve the individual record to be edited, and populate the "change" form.
Run query:
<cfquery name="cfqGetItem" datasource="#datasource#">
SELECT *
FROM #query_tbl#
WHERE ID = <cfqueryparam value="#URL.ID#" cfsqltype="cf_sql_integer">
</cfquery>
My "change" form (abbreviated here without table HTML) to be populated would be:
<form name="form_item_chg" action="chg_item2.cfm" method="post" enctype="multipart/form-data">
<input type="text" name="#column1_field#" maxlength="#column1_input_maxlength#" size="#column1_input_size#" value="#cfqGetItem[column1_field][currentRow]#">
<input type="Submit" value="Post Changes">
</form>
However, instead of the "change" form being populated with the VALUE for field "role", it instead is trying to use the variable name "column1_field", which it says is (true, of course) undefined in the query.
When I tried "#cfqGetItem[column1_field][currentRow]#", it says "Variable currentrow is not defined".
When I tried "#cfqGetItem.column1_field#", it says "Element column1_field is not defined in query cfqGetItem".
I apologize in advance for not knowing/using all the correct terminology, and hope I am explaining this reasonably clearly. I suspect I will have to revert to writing individual form-page/action-page pairs. Thank you to all for your time and help!
ORIGINAL POST:
I'm not highly technical, and this is probably something simple, but here is
my dilemma, where I am attempting to retrieve a single record using a variable name in the query.
First, I define some variables:
<cfset ID = #Form.ID#<!--- the single record I want to retrieve, passed from a form --->
<cfset datasource = 'MyDatabase'>
<cfset query_tbl = 'MyDatabaseTable'>
<cfset field1 = 'actual_fieldname1'><!--- field in MyDatabaseTable --->
<cfset field2 = 'actual_fieldname2'><!--- field in MyDatabaseTable --->
ETC.
Then, to retrieve this single record, I run a query using those variables:
<cfquery name="cfqGetItem" datasource="#datasource#">
SELECT *
FROM #query_tbl#
WHERE ID = #ID#
</cfquery>
Then, I attempt to display the query output:
EITHER AS
<cfoutput>
<p>#cfqGetItem.field1#
<p>#cfqGetItem.field2#
</cfoutput>
OR, AS
<cfoutput>
<p>#cfqGetItem[field1][currentRow]#
<p>#cfqGetItem[field2][currentRow]#
</cfoutput>
In each case, I get a similar CF error message: "Element field1 is not defined in query cfqGetItem", or "Variable currentrow is not defined".
How can I get the query output to generate the actual values for the record instead of the variable names?
Thank you very much for any help!
If you change this:
<cfoutput>
<p>#cfqGetItem[field1][currentRow]#
<p>#cfqGetItem[field2][currentRow]#
</cfoutput>
to this:
<cfoutput>
<cfloop query="cfqGetItem">
<p>#cfqGetItem[field1][currentRow]#
<p>#cfqGetItem[field2][currentRow]#
</cfloop>
</cfoutput>
You should be ok. However, this is the simplest way
<cfoutput query="cfqGetItem">
<p>#actual_fieldname1#
<p>#actual_fieldname1#
</cfoutput>
Setting the table and field names to variables complicates matters. Unless they really can vary, don't do it. Also, the cfqueryparam tag is your friend. Use it in places like this:
where id = <cfqueryparam
cfsqltype = "cf_sql_integer"
value = "#id#">
You can try out like this also:
<cfquery
name="GetParks" datasource="cfdocexamples"
>
SELECT PARKNAME, REGION, STATE
FROM Parks
ORDER BY ParkName, State
</cfquery>
<cfoutput>
<p>#GetParks.PARKNAME#
<p>#GetParks.REGION#
</cfoutput>
<cfoutput >
#GetParks['state'][GetParks.RecordCount]#
</cfoutput>
<cfoutput >
#GetParks['state'][2]#
</cfoutput>
Related
This question already has answers here:
Dynamic Variable Naming and Reference (ColdFusion)
(2 answers)
Getting complex object error when trying to output query values
(1 answer)
Closed 6 years ago.
I am trying to set dynamic query column headers to get their values from a query.
<cfoutput query="qryGetData">
<cfloop from="-18" to="18" index="i">
<cfif i GTE 0>
<cfset variables["target_MonthPlus_#abs(i)#"] = "Testing" />
<td>
<cfoutput>#variables["target_MonthPlus_#abs(i)#"]#</cfoutput>
</td>
<cfelse>
<cfset variables["target_MonthMinus_#abs(i)#"] = "Testing" />
<td>
<cfoutput>#variables["target_MonthMinus_#abs(i)#"]#</cfoutput>
</td>
</cfif>
</cfloop>
Code I have does not really work, I found it from another answer and I have tried all I can think of and tried using EVALUATE() even though I know I should not use.
So basically my query has 37 month fields starting from target_MonthMinus18 to target_MonthMinus1. And then target_MonthPlus0 to target_MonthPlus18. I have taken care of that plus and minus with the CFIF as you can see above. So only other thing different is that value of the month.
Closest things I have got to actually name the columns dynamically is something like this, but this just outputs the name of the column, which would return target_MonthPlus0, target_MonthPlus1, targetMonthPlus2, etc.
But I need to use that name to return the actual value of the columns from the query.
<cfif i GTE 0>
<cfset monthInLoop = "target_MonthPlus_" & #ABS(i)#>
<td>
<cfoutput>#monthInLoop#</cfoutput>
target_monthMinus18 is a column name that may return a value of 100 from qryGetData that I need to display in its td
target_monthMinus17 is a column name that may return a value of 95 from qryGetData that I need to display in its td
target_monthPlus17 is a column name that may return a value of 205 from qryGetData that I need to display in its td
and so on...We are always going back 18 months in the past and 18 months in future as you can tell.
I have found several questions similar to this and have applied to my code but somehow they are trying to do different things or I still do not understand what I am doing wrong.
Thanks in advance for your help :)
PC
I think you may be over thinking this. You can access your columns directly from within the query using something like this:
<cfloop query="qryGetData">
<cfloop from="-18" to="18" index="i">
<cfif i GTE 0>
<td>
<cfoutput>#qryGetData["target_MonthPlus_" & abs(i)][currentrow]#</cfoutput>
</td>
<cfelse>
<td>
<cfoutput>#qryGetData["target_MonthMinus_" & abs(i)][currentrow]#</cfoutput>
</td>
</cfif>
</cfloop>
</cfloop>
This takes advantage of CF's query array syntax. Keep in mind you also have qryGetData.columnlist to work with (a list of all your columns). You might be able to work with that creatively as well.
I have a struct that contains 2 queries. I have a variable with the "key" of one of the queries, and I want to output the query dynamically using that variable. My basic code:
<cfquery name="myQueries.names" ... >...</cfquery>
<cfquery name="myQueries.places" ... >...</cfquery>
<cfset queryName = "places" />
<cfoutput query="myQueries[queryName]">
...
</cfoutput>
This gives me the error Attribute validation error for tag cfoutput.
The cfoutput "query" attribute doesn't seem to support bracket notation. How can I access the query from the cfoutput?
The query attribute of cfoutput requires a valid variable name, so you can set an intermediary value and use that to reference your query
<cfset realQuery = myQueries[queryName]>
<cfoutput query="realQuery">
...
</cfoutput>
I am new to ColdFusion and want to rewrite my project from ASP.NET to learn ColdFusion step by step.
My SQL Server stored procedure for authentication (ASP.NET) looks like this:
CREATE PROCEDURE sp_auth
#suser VARCHAR(20),
#spswd VARCHAR(20)
AS
SELECT COUNT(*) FROM Users.SUsers WHERE suname=#suser AND supasswd=#spswd AND off_bit=0
GO
Application.cfc snippet.
<cfstoredproc procedure="sp_auth" datasource="cftraderelay">
<cfprocparam value="#cflogin.name#" cfsqltype="CF_SQL_VARCHAR" maxlength="20" type="in">
<cfprocparam value="#cflogin.password#" cfsqltype="CF_SQL_VARCHAR" maxlength="20" type="in">
<cfprocresult name="auth_pass" maxrows="1">
</cfstoredproc>
<cfif auth_pass GTE 1>
<cfloginuser name="#cflogin.name#" password = "#cflogin.password#" roles="#roles#">
<cfelse>
<cfoutput>
<h2>Your login information is not valid.<br> Please Try again</h2>
</cfoutput>
<cfinclude template="login.cfm">
<cfabort>
</cfif>
What is right form of 'cfif auth_pass GTE 1' logic? How to access the value of 'auth_pass'.
Cos I get "Complex object types cannot be converted to simple values" error by far.
Am I strictly supposed to use out type of cfprocparam in this case, not cfprocresult (modify SQL query for the OUTPUT variable)?
Can I access cfprocresult value right in the cfif statement?
auth_pass contains a recordset, not a number, so you cannot compare it to 1. You perhaps want auth_pass.recordCount?
The best tool for examining the contents of a variable is <cfdump>. That and familiairising yourself with the docs for the code you're using, eg: <cfprocresult>, <cfstoredproc>, <cfquery> (the latter for details on query objects) if you run into problems and can't guess the solution.
This question already has answers here:
Coldfusion - variable field name when looping through database query results
(2 answers)
Closed 9 years ago.
Edit: The QUESTION is a duplicate, but the ANSWER is not!
I have the following code:
<cfquery name="contact" datasource="thesource">
SELECT * FROM #table# WHERE foo = '#bar#'
</cfquery>
and then later on (this is the problem part):
<cfloop from="0" to="9" index="i">
<cfset thisvar = Evaluate("contact.check" & i) />
<cfoutput>
#thisvar#
</cfoutput>
</cfloop>
Upon execution, it throws a nice big "Variable contact.check0 is Undefined". However, #contact.check0# will output just fine if hardcoded.
Any ideas on how to fix this?
Note:
I have seen Coldfusion - variable field name when looping through database query results, and although the problem seems to be exactly the same, the solutions do not work. As per the comments, I am also getting a "cannot be converted to a number" error. I notice Tomalak mentions "a little catch", but never says what it is. In the article he links to, I have tried every syntactically equivalent form, and it all throws an error...either cannot convert to a number or is not defined.
Also, I'm aware Evaluate() has overhead and "should not be used". I'll take any solution that works, whether it has Evaluate in it or not.
This is on ColdFusion 9.
Thank you
Edit: while a similar question already had an answer, this question had a different cause. See accepted answer below.
First of all, standard blub about escaping inputs. cfqueryparam exists for a reason. That aside you can do this without evaluate. Give this a try instead, including a check to make sure there is actually a result
<!--- make sure that there is actually a result --->
<cfif contact.RecordCount EQ 0>
NO RESULT
<cfelse>
<cfloop from="0" to="9" index="i">
<!--- assumes that you want row 1 --->
<!--- check.CurrentRow could also be used instead of 1 --->
<cfset thisvar = contact['check'&i][1] />
<cfoutput>
#thisvar#
</cfoutput>
</cfloop>
</cfif>
I suspect that it is attempting to Evaluate the column without specification of the row number, while when hard-coding it you'll find it uses the current row.
edit as Dan Bracuk pointed out this is an exact duplicate of the question you linked in your question, Coldfusion - variable field name when looping through database query results
This is ridiculous and absurd. Working code (moved things around a bit):
<cfoutput>
<cfloop from="0" to="9" index="i">
<cfset thisvar = contact["check"&i][1] />
#thisvar#
</cfloop>
</cfoutput>
NOT working code:
<cfoutput query="contact"> <!--- this line here --->
<cfloop from="0" to="9" index="i">
<cfset thisvar = contact["check"&i][1] />
#thisvar#
</cfloop>
</cfoutput>
Someone else had put cfoutput tags around the whole page. While this normally wouldn't be a problem, they ALSO declared the query attribute. This somehow overwrote the original query from the db. Calling contact.check0 worked just fine, but building the variable name dynamically, I think, was attempting to reference the cfoutput's query attribute.
Thanks to Peter Boughton for the suggestion to extract the problem code...which led me to this realization, and Simon for posting the syntactically correct code. Points go to them.
The basic idea is this: I have a form that generates form fields dynamically so let's say there are 5 evens people can sign up for (they all cost $10) then those 5 evens will be displayed. Like this:
<tr>
<th><label>#SeminarWisTitle#</label></th>
<td>
<label><input type="checkbox" name="#SeminarWisID#" value="10.00" onclick="CheckChoice(this);" onfocus="startCalc();" onblur="stopCalc();" class="checkbox" /> Individual Webinar ($119)</label>
</tr>
</cfoutput>
Now because of the Javascript the value on all these events will be 10.00 but the NAME of the form field will be unique, and that is what I actaully want to store in the database.
This is the code I've written:
<cfparam name="seminarBulkSignUp_List" default="">
<cfoutput query="qSeminarWisTwo">
<cfparam name="FORM.#SeminarWisID#" default="">
<cfif #FORM[#SeminarWisID#]# neq "">
<cfset seminarBulkSignUp_List = ListAppend(seminarBulkSignUp_List, #FORM[#SeminarWisID#]#)>
</cfif>
</cfoutput>
<cfset FORM.SeminarWisTitle = #seminarBulkSignUp_List#>
So with this code, I run a query for ALL the possible events, and then just check against the form that has been submitted to see which ones are "blank" as in not selected, and the ones that are selected i want to add to a list to store in the database.
Now this works as far as letting me know which events were selected and which not, but i want the list to compile the actual FORM FIELD names not the value they have. How would I do that?
<cfoutput>
<cfloop list="#StructKeyList(FORM)#" index="thisField">
My field name: #thisField#<br/>
My field value: #FORM[thisField]#<br/>
</cfloop>
</cfoutput>
Apply as necessary.