I am from a PHP background and am very new to ColdFusion. I am using ColdFusion-10
I have created two files: a cfm file and a cfc file. When I am executing a query using cfquery in cfm file it is working. But when I am executing same in a cfc file, and calling the function in the cfm file, its throwing an error, saying the table name does not exist.
cfquery in both the files:
<cfquery name="test" dbtype="query">
SELECT * FROM tbl_name
</cfquery>
In your query you've specified dbtype="query". To CF that is telling it to query a query you have previously run on the page somewhere. In the CFC that query is probably not available because it was not passed in hence the error.
Maybe you mean to use this below and query your data source and not a query?
<cfquery name="test" datasource="{put your CF datasource name here}">
SELECT * FROM tbl_name
</cfquery>
Related
I have a datasource called "cforms" which has access to two database
"cforms" and "cquizes"
I wish to create the following query:
select * from cquizes.tb_depts;
I have a model for table "tb_depts":
<cfcomponent extends="Model">
<cffunction name="init">
<cfset table("tb_depts")>
</cffunction>
</cfcomponent>
And my controller:
list = model("tb_depts").findAll(order="id");
When I run this controller/action. It gives me the following error:
[Macromedia][Oracle JDBC Driver][Oracle]ORA-00942: table or view does not exist
And it generates the following query:
SELECT * FROM tb_depts
I understand what the problem is because since "tb_depts" doesn't exist in database "cforms" it throws that not found error. However is there are way to tell the model that using the datasource "cforms" access database "cquizes". For example
cquizes.tb_depts
Its seems to use the database that matches the datasource name. Is there a way to work around this functionality.
If you need to get data from another database, There is an alternative way. For that you need to create a datasource for your second database cquizes. Then use that datasource name in the model file. This will override default datasource for that model.
For example, If you name your second datasource as cquizdatasource then in your model would be like
<cfcomponent extends="Model">
<cffunction name="init">
<cfset dataSource("cquizdatasource")>
<cfset table("tb_depts")>
</cffunction>
</cfcomponent>
Your query should work fine with the said scenario in the question. There are limitations to this, check out the link to know more.
I have an cfmail function set-up in a particular file, email_output.cfm, which requires an ID passed to it to work properly, like email_output.cfm?ID=1. I want to set up a cron job that runs through a query returning the various needed IDs to pass. In testing, I can do the following:
<cflocation url="email_output.cfm?ID=10" >
But, since cflocation stops all other execution and opens another page, I can't loop through it. How would I pass parameters from a query to a single CF page multiple times?
Thanks - Joe
A custom tag sample implementation of this...
If this is your first time using a custom tag, it's easiest to put it in the same folder as the page calling it. There are a few options for putting it in a different directory, but let's start simple.
EmailMembers.cfm
<cfquery name="GetUIDs">
select userid from users
</cfquery>
<cfoutput query="GetUIDs">
<cf_maileach uid="#userID#">
</cfoutput>
Notice how I called my tag cf_maileach?
In the same directory, place maileach.cfm, see how the names match?
maileach.cfm
<cfif StructKeyExists(attributes,"uid") and val(attributes.uid) gt 0>
<cfquery name="getinfo">
select fname,lname,email
from users
where userID = <cfqueryparam cfsqltype="cf_sql_integer" value="#attributes.uid#">
</cfquery>
<cfmail to="#getinfo.email#" subject="Hi #getinfo.fname#">...</cfmail>
</cfif>
Notes
Depending on your version of cf, and whether you're using application.cfc or not, there are several ways to place a custom tag in an outside directory. There is also <cfmodule>
This is a sample only, something this basic is redundant, I was just trying to mimic what asker outlined. In this sample, I'm calling a query that could get all the data, only to use it to query row by row.
If you're not familiar with <cfqueryparam>, look it up, use it, love it.
Edit: While a CFHTTP method can serve this purpose, it suffers a few problems
Sessions are not automatically passed (even if the requesting server and destination server are the same.).
The page is accessed like a browser request. Application/OnRequestEnd are processed (and since session info is passed as well, this can cause problems trying to access files in secured areas.
Because of the above, the page would need to be in a folder with its own Application file to negate any application files above it in the directory hierarchy.
To combat 1, 2, and 3, You'd need to code in a layer of security, similar to your application's own security, so that the file is not vulnerable should the url be found.
Each call to the file via cfhttp would need to invoke some extra security checking.
It is significantly slower. In a very simple test with a zero-content application.cfc, the custom tag method was executing in literally <= 1/100th of the time. As actual function is added to the method, the difference in results would change.
Here is some sample code to test this yourself.
Contents of folder "safe":
Application.cfc
[ blank file, to negate my testing site's actual application.cfc ]
Testrun.cfm
<cfoutput><cfset starttick = GetTickCount()>
<cfloop from="1" to="20" index="i">
<cfhttp url="http://mysamesite.com/safe/http.cfm?u=#i#" method="get" result="test">
#test.filecontent#<br>
</cfloop>
CFHTTP Execution Time: #(GetTickCount() - starttick)#<br><br>
<cfset starttick = GetTickCount()>
<cfloop from="1" to="20" index="i">
<cf_testtag u="#i#"><br>
</cfloop>
CustomTag Execution Time: #(GetTickCount() - starttick)#<br><br>
</cfoutput>
testtag.cfm
<cfoutput>The ID entered was #attributes.u#</cfoutput>
http.cfm
<cfoutput>The ID entered was #url.u#</cfoutput>
Results (in milliseconds)
Each test was 20 passes at HTTP and 20 Passes at the custom tag.
CFHTTP Tag
661ms 6ms
1624 5
616 5
460 4
522 6
816 4
You can do this by using cfhttp also
<cfquery name="GetUIDs">
select userid from users
</cfquery>
<cfloop query="GetUIDs">
<cfhttp url="http://localhost:8500/cf10/test.cfm?id=#userid#" method="get" result="test">
</cfloop>
I'm working with ColdFusion 11 and am getting an error with cftransaction. I'm not sure what causing it.
I have two CFC's: abc.cfc and xyz.cfc. abc.cfc does not use the datasource attribute: as it is defined in the Application.cfc using this.datasource.
Here is the error:
Error! The root cause was that: java.sql.SQLException: Usernames and Passwords for all the database tags within the cftransaction tag must be the same. Datasource inventorymgt verification failed.. Entry rolled back
What I am doing is:
<cftransaction action="begin">
<cftry>
<cfscript>
f = structNew();
f.companyName = '#arguments.structform.companyname#';
f.address = '#arguments.structform.address#';
f.settingsID = arguments.structform.settingsID;
r = tblUpdate('settings',f);
sresult = 'Updated';
</cfscript>
<cfset str = "Cool! Settings has been " & sresult>
<cftransaction action="commit"/>
<cfcatch type="any">
<cftransaction action="rollback"/>
<cfset str = "Error! #cfcatch.Detail# #cfcatch.Message#. Entry rolled back">
</cfcatch>
</cftry>
</cftransaction>
And another CFC which is expecting the init function like the datasource, username,password is using the following query way to update it:
<cfquery name="q"
datasource="#variables.dbsource#"
username="#variables.dbuname#"
password="#variables.dbpword#">
I think the reason is explained in this post:
https://groups.google.com/forum/#!topic/cfwheels/AZTvxvhsapc
Within a cftransaction tag, every query has to use the same authentification. You cannot have one query use a datatasource and the other use a username and password within the same transaction.
I would agree with the author of the link. I always just define the datasource once in the cf-administrator, so I don't have to deal with username/password. Then you can initialize your cfc just by datasource.
I don't know what your function tblUpdate is actually doing, but might be that you use a different syntax than in the query you posted? Because, that's what your error code says:
Usernames and Passwords for all the database tags within the cftransaction tag must be the same.
I am trying to create a spreadsheet (.XLS file) using Adobe ColdFusion - 8.
The code that creates a spreadsheet is:
<cfsetting enablecfoutputonly="Yes">
<cfset date_from = "#URL.date_from#">
<cfset date_to = "#URL.date_to#">
<cfset query_id="#URL.queryID#">
<cfquery name="GetEmps" datasource="cfdocexamples">
<!--- My SQL Queries Goes Here--->
</cfquery>
<cfcontent type="application/msexcel">
<cfheader name="Content-Disposition" value="filename=Employees.xls">
<cfoutput>
<table cols="4">
<cfloop query="getData">
<tr>
<td>#uid#</td>
<td>#week#</td>
<td>#book_count#</td>
</tr>
</cfloop>
</table>
</cfoutput>
Whenever I run the page, an XLS sheet is created, but I cannot find any data. The size of the created XLS file is 0.
Please Note: The Query is correct(Since when I print the output as html, I can see the table without any error/warning).
** After reading comments: UPD**:
I had updated my code and only included important code snippet now.
UPD 2:
Whenever I commented the line <cfsetting enablecfoutputonly="Yes"> , xls file is created with expected data. However, when I opened the generated file, a dialogue appears:
Please note the spreadsheet generated is perfect. Only thing that is bothering me is the above warning.
Also Note: whenever I tried to open the spreadsheet in google-docs as a preview, it says, the file could not be opened due to corrupted format.
However, I am able to open it perfectly in an MS-Excel.
Even changing content type to : <cfcontent type="application/vnd.msexcel"> , I got the same warning.
While I cannot speak exactly how to implement this, I know the developers within my organization worked around it with the Apache POI. It seemed to do the trick for them. It does have to be completed with Java through Coldfusion. Here is an example of it.
Question: I have a CFM calling my CFC on the cfform action line:
In my CFC, I have output="false". I am needing the record count sent back to my CFM. When I run my CFM and enter the form info my queries are running successfully, but it is not coming back to my CFM so I can display the proper messages. I just get the CFC page with my record count. Any suggestions? Thanks!
Since there's no code, making a few assumptions here about how you're doing things ....
Don't point to the CFC, point to a CFM page in your <cfform>. (If you omit the action, it'll point back to itself.. I like self-referencing form pages)
In your CFC, return the result struct from your query:
<cfquery datasource="#ds#" name="myQuery" result="myResult">
INSERT INTO myTable .....
</cfquery>
Then either return that entire struct, or just myResult.recordCount:
<cfreturn myResult.recordCount>
Then in your CFM page, you'll access it like so (assuming you're using <cfscript>; similar if you're doing tag-based):
recordsAdded = createObject('component','myFolder.myCFC').insertMethod(form);
I changed the cfform line to this:
....rest of my form
then added these lines to see if the form was submitted and what action is:
<!--- create object for cfc --->
But now, my query is not running....