ColdFusion CLIENT cookie issue

MSSQL error: The data types text and varchar are incompatible in the equal to operator.

In the ColdFusion administrator under there is the option to save CLIENT variables as cookies, in the registry, a datasource or not at all.

If the client variables are stored as cookies, it is fairly easy to retrieve and parse to determine things like the identity of a returning user from the cookie. This cookie is called CFCLIENT_<cfapplication name>. If the client variables are stored in the database, it's not so easy. Actually impossible, the cookie variables are NOT stored in the datasource.

First to locate the CLIENT variables, which are stored in a table called CDATA. CFGLOBALS client variables are session variables, like CFID, CFTOKEN and timestamp details and are stored in the table CGLOBAL.

So what about the error? The data types text and varchar are incompatible in the equal to operator. I ran some queries to try and see if there was some information I could glean from the client variables table.

view plain print about
1SELECT TOP 1000 [cfid]
2 ,[app]
3 ,[data]
4 FROM [hoton].[dbo].[cdata]
5 where [data] != ''
Error: The data types text and varchar are incompatible in the not equal to operator.

[data] is a text field permitting nulls. So I checked for null:

view plain print about
1SELECT TOP 1000 [cfid]
2 ,[app]
3 ,[data]
4 FROM [hoton].[dbo].[cdata]
5 where [data] is null
pulled up everything, to test, I ran this:
view plain print about
1SELECT TOP 1000 [cfid]
2 ,[app]
3 ,[data]
4 FROM [hoton].[dbo].[cdata]
5 where [data] is not null
which turned up nothing! So I added a space in the quotes:
view plain print about
1SELECT TOP 1000 [cfid]
2 ,[app]
3 ,[data]
4 FROM [hoton].[dbo].[cdata]
5 where [data] != ' '
The data types text and varchar are incompatible in the not equal to operator.
No go! But this worked:
view plain print about
1SELECT TOP 1000 [cfid]
2 ,[app]
3 ,[data]
4 FROM [hoton].[dbo].[cdata]
5 where [data] not like ''
which pulled up what I wanted to look at, but unfortunately could not use. No cookie info is stored in with the datasource client session storage option in the ColdFusion administrator.

CFM Pages Not Working After Server IP Change

BlueOnyx JSP and Servlets, including ColdFusion, CFM, CFML, Railo templates do not run after changing the IP address of the site and server. CFM displays as text.

Datacenter adjustments forced a change in IP addresses for my BlueOnyx server. The IP address of the server, and subsquently, the IP addresses of each of the sites within, had to be changed. Not a big issue, but then all of the CFM pages displayed as text. Not cool.

When the IP address was changed through the BlueOnyx Admin GUI, all of the vhosts were changed, inadvertantly dropping the JSP and Servlet switches. This can be added back either manually entering or through the GUI.

Option 1
Manually entering: find your SiteID for the site.

view plain print about
1basename $(ls -l /home/sites/| grep www.example.tld | awk '{ print $11}')

Then edit the vhosts file, using the correct SiteID

view plain print about
1vi /etc/httpd/conf/vhost/site1

adding back the JSP code:

view plain print about
1# BEGIN JSP SECTION. DO NOT EDIT MARKS OR IN BETWEEN.
2JkMount /* ajp13
3JkMount /*.jsp ajp13
4JkMount /servlet/* ajp13
5# END JSP SECTION. DO NOT EDIT MARKS OR IN BETWEEN.

Then restart httpd:

view plain print about
1/etc/init.d/httpd restart

Now you should be serving up those fancy CFM pages.

Option 2
Through the GUI, in the Web settings for the site, uncheck Enable JSP and Servlets and save. When it finishes saving and resetting, recheck or enable Enable JSP and Servlets and save. This will add 2 lines of the above code block, but you still need to add this to run CFML.

view plain print about
1JkMount /* ajp13

So you still have to edit vhosts (SiteID!)

view plain print about
1vi /etc/httpd/conf/vhost/site1

Change the JSP section from this:

view plain print about
1# BEGIN JSP SECTION. DO NOT EDIT MARKS OR IN BETWEEN.
2JkMount /*.jsp ajp13
3JkMount /servlet/* ajp13
4# END JSP SECTION. DO NOT EDIT MARKS OR IN BETWEEN.
to this:
view plain print about
1# BEGIN JSP SECTION. DO NOT EDIT MARKS OR IN BETWEEN.
2JkMount /* ajp13
3JkMount /*.jsp ajp13
4JkMount /servlet/* ajp13
5# END JSP SECTION. DO NOT EDIT MARKS OR IN BETWEEN.

Then restart httpd:

view plain print about
1/etc/init.d/httpd restart

Back in business, running your fantastice CFML site!

Ubuntu Mounting HTC One M8 SD Card

error: exited with non-zero exit status 32: mount: unknown filesystem type 'exfat'

I added a 64 Gigabyte SDcard to my HTC One M8 phone and could not connect to add music or files. The issue is that Ubuntu 14.01 cannot read exFAT formatted drives, which includes most SDCards.

We have to enable exFAT in Ubuntu 14.01 using fuse. Fuse is already in Ubuntu but we have to install the exFAT packages.

view plain print about
1sudo apt-get install exfat-fuse exfat-utils

Then uplug your phone from the USB port and plug it back in. Then, in your phone, go into settings (I just scrolled the top bar down) and tap USB File sharing - USB file sharing mode. Then enable Disk Drive - Mount as disk drive.

In just a second you will than be able to see your SDCard in File Manager. Start dragging and dropping your folder onto your phone.

Block Special Characters from a Text Box Form Input

We want to keep users from entering special characters into our textbox input on or form. Ideally we want to not allow those characters to be entered at all, as opposed to let them enter the characters, check to see if they did, and then alerting them. Too much work, simply keep them from entering special characters from the beginning. For this we'll use JavaScript's onKeyPress event, which looks like this:

view plain print about
1<input type="text" onkeypress="myFunction()">

We'll construct a function that will check for special characters. And, well, here it is:

view plain print about
1function isAlphaNum(event) {
2 var regex = new RegExp("^[a-zA-Z0-9\\s]+$");
3 //alert(event + ' - ' + regex);
4 var key = String.fromCharCode(!event.charCode ? event.which : event.charCode);
5 if (!regex.test(key)) {
6 event.preventDefault();
7 return false;
8 }
9}

A quick walk through of the code.... the function is called "isAlphaNum()". The regex we are checking against is "^[a-zA-Z0-9]+$", which checks for numbers and upper and lowercase letters. I wanted allow spaces too, so I added the "\\s" to make it "^[a-zA-Z0-9\\s]+$". The commented alert is for testing. The function checks to see if the keypress does NOT match the expression and returns false. It does nothing if it passes the regex test.

My final HTML form text box looks like:

view plain print about
1<input type="text" onkeypress="isAlphaNum(event);">

Try it out! You will be unable to type in a character other than a number, letter or space.

MSSQL Remove duplicate records

MSSQL Remove duplicate records from a table leaving a single unique record.

The situation arose where we had multiple records for items where there should be only a single record. We have JobIDs which will have multiple unique TaskIDs. We found we several (lots) of JobIDs which had 2 of the same TaskIDs. It's OK to have many TaskIDs in each job, there just can't be 2 of the same TaskIDs per JobID. Many TaskIDs to one JobID and one unique TaskID to one JobID.

First we find which TaskIDs are duplicated.

view plain print about
1Select DISTINCT TaskID FROM (
2select JobID, TaskID, (*) as Count from JobTable
3Where TaskID IS NOT NULL
4Group by JobID, TaskID HAVING COUNT(*) >
1) X

We are going to remove the 2nd entry for each duplicate TaskID. The original TaskID is correct in this case. The 2nd TaskID is superfluous and will have a greater Identity Key, they were added at a later time. Let's pull up the duplicate TaskIDs with the larger Identity Key (ID).

view plain print about
1SELECT T1.ID
2FROM JobTable T1
3JOIN
4(SELECT JobID,TaskID , MAX(ID) AS ID FROM JobTable
5GROUP BY JobID,TaskID
6Having COUNT(*) >
1) AS T2
7ON T1.TaskID = T2.TaskID AND T1.Qbid = T2.QBID AND T1.ID = T2.ID

This pulls up what we want, so lets get rid of them.

view plain print about
1DELETE JobTable WHERE ID in (
2SELECT T1.ID
3FROM JobTable T1
4JOIN
5(SELECT JobID,TaskID , MAX(ID) AS ID FROM JobTable
6GROUP BY JobID,TaskID
7Having COUNT(*) >
1) AS T2
8ON T1.TaskID = T2.TaskID AND T1.Qbid = T2.QBID AND T1.ID = T2.ID
9)

Done! Now we have unique TaskIDs for each JobID.

Find Duplicates in MSSQL

Find duplicate entries in MS SQL table columns. Need to see if you have 2 or more duplicate entries in your table? Want to find out if the key is really unique and there are not multiples? Simple!

view plain print about
1SELECT [ID], COUNT([TaskID])as NumberOfDups
2FROM [dbo].[MyBigTable]
3GROUP BY ID,[TaskID]
4HAVING (COUNT([TaskID]) >
1 )

ID = the identifier, could be a name or whatever
TaskID = looking for duplicates of this

Trouble with cfloop lists and arrays with cfqueryparam

I was looping an array and and using each item in a cfqueryparam. Running a query in each loop. Each iteration was displaying a null query result, which was incorrect. The same problem occurred with a list of the same items.

The simple answer was to surround the cfqueryparam value with the Trim() function! It worked with the list loop too.

view plain print about
1<cfqueryparam value="#Trim(MSArray[j])#" cfsqltype="CF_SQL_VARCHAR">

Here is my effort:

view plain print about
1<cfset MSList = "
2010,
3020,
4004,
5075.5,
6027,
7030,
8020.5,
9021,
10023,
11041,
12041.1,
13041.5,
14041.3,
15040,
16080,
17102,
18088.1,
19095,
20104.5,
21104.1,
22104.3,
23110,
24096,
25100,
26107.1,
27112,
28124,
29025,
30101,
31143,
32143.1,
33126,
34132,
35146,
36149,
37153,
38154,
39155,
40160
41"

42/
>

43
44<cfloop list="#MSList#" index="j">
45    <cfquery datasource="#myDataSource#" name="getID">
46         SELECT [ID]
47         FROM     [dbo].[MS_Table]
48         where [Activity_ID] = 1
49         and     [MS] = <cfqueryparam value="#Trim(j)#" cfsqltype="CF_SQL_VARCHAR">
50    </cfquery>
51    <cfdump var="#getID#">
52</cfloop>

Custom Logging Template for SQL queries and Stored Procedures

We'll combine the last two blog posts, Where Does CF Debug Information Come from Mommy? Or How to use the ColdFusion Service Factory and ColdFusion Custom Debugging Template. The task is to create a template to log any database activity, specifically looking for consistently long running queries and to make a baseline for our code optimization.

Let's take a look at the data we are gathering. I created this table to keep data which I thought would be pertinent.

Hey this image will be loaded soon!

Here's a key explaining the basics on this table:
ATTUID = individual user id
RequestID = Individual ID per request (more below)
Body = the actual query
Line = line number of query or stored procedure
Name = assigned name of query or stored procedure
CFScript = not what you think, this is the script name calling the query or stored procedure
CFTimeStamp = ColdFusion's time stamp
SQLTimeStamp = MS SQL's time stamp
Type = query or stored procedure

Now the code...
First we'll utilize the ColdFusion Service Factory:

view plain print about
1<!--- initialize the CF Server's Service Factory --->
2<cfset factory = createObject("java","coldfusion.server.ServiceFactory") />
3<!--- get all the debugging data --->
4<cfset queries = factory.getDebuggingService().getDebugger().getData() />
We create the logging service by calling Illudium PU-36 generated beans and DAO (Data Access Objects). Basically these are the getters and setters.
view plain print about
1<!--- Set up Logging Service - call it once and reuse it --->
2<cfset CFLog = createObject("component","optimization.cfc.Optimization_Code_Log").init() />
3<cfset CFLogger = createObject("component","optimization.cfc.Optimization_Code_LogDAO").init(application.sqlSource) />

Add this in to help keep individual page requests identified together.

view plain print about
1<!--- Unique ID per request --->
2<!--- keep all requests per page call together --->
3<cfset RequestID = Val(Replace(Rand(),"0.","")) />
A little detail about this... I desired a random number be generated but wanted it to be a whole number. The Rand() function creates a decimal. I am treating the Rand() produced number as string, removing the preceding "0.", and converting to a number with the Val() function. The number length varied, so multiplication would not be work.

To get the data we want we are going to query the debugging data, "queries" called above, as shown below:

view plain print about
1<cfquery dbType="query" name="cfdebug_queries" debug="false">
2    SELECT *, (endTime - startTime) AS executionTime
3    FROM queries
4    WHERE type = 'SqlQuery'
5</cfquery>

Two things of note. One is the calculation of Execution Time, really what we are after, and the type = 'SqlQuery'. For Stored Procedures, we replace this with "StoredProcedure".

view plain print about
1<cfquery dbType="query" name="cfdebug_storedproc" debug="false">
2    SELECT *, (endTime - startTime) AS executionTime
3    FROM queries
4    WHERE type = 'StoredProcedure'
5</cfquery>

Loop the query containing all the debug data for queries run on your template, then set the data in the bean using the Illudium PU-36 setters, e.g. CFLog.setBlahBlah(variablescope.blahblah). Once they are all set, then we save using the generated DAO.

view plain print about
1<cfloop query="cfdebug_queries">
2
3    <cfset CFLog.setATTUID(client.ATTUID) />
4    <cfset CFLog.setRequestID(RequestID) />
5    <cfset CFLog.setBody(cfdebug_queries.Body) />
6    <cfset CFLog.setDatasource(cfdebug_queries.Datasource) />
7    <cfset CFLog.setIPAddress(CGI.REMOTE_ADDR) />
8    <cfset CFLog.setEndTime(cfdebug_queries.EndTime) />
9    <cfset CFLog.setExecutionTime(cfdebug_queries.ExecutionTime) />
10    <cfset CFLog.setLine(cfdebug_queries.Line) />
11    <cfset CFLog.setName(cfdebug_queries.Name) />
12    <cfset CFLog.setCFRowCount(cfdebug_queries.RowCount) />
13    <cfset CFLog.setStartTime(cfdebug_queries.StartTime) />
14    <cfset CFLog.setCFScript(CGI.SCRIPT_NAME) />
15    <cfset CFLog.setURLString(CGI.QUERY_STRING) />
16    <cfset CFLog.setTemplate(cfdebug_queries.Template) />
17    <cfset CFLog.setCFTimeStamp(cfdebug_queries.TimeStamp) />
18    <cfset CFLog.setSQLTimeStamp(Now()) />
19    <cfset CFLog.setType(cfdebug_queries.Type) />
20
21    <cfset CFLogger.save(CFLog) />
22</cfloop>

You can see that we are gathering more information than what was provided from the service factory, for example, the client user id, and several CGI variables.

We do the same thing for the Stored Procedures, except for one small but important change. Note also that I do not have to create another set of bean and DAO objects, I just reuse the existing ones, CFLog and CFLogger.

view plain print about
1<cfloop query="cfdebug_storedproc">
2
3    <cfset CFLog.setATTUID(client.ATTUID) />
4    <cfset CFLog.setRequestID(RequestID) />
5    <cfset CFLog.setBody(cfdebug_storedproc.Body) />
6    <cfset CFLog.setDatasource(cfdebug_storedproc.Datasource) />
7    <cfset CFLog.setIPAddress(CGI.REMOTE_ADDR) />
8    <cfset CFLog.setEndTime(cfdebug_storedproc.EndTime) />
9    <cfset CFLog.setExecutionTime(cfdebug_storedproc.ExecutionTime) />
10    <cfset CFLog.setLine(cfdebug_storedproc.Line) />
11    <cfset CFLog.setName(cfdebug_storedproc.result[cfdebug_storedproc.currentRow][1].name) />
12    <cfset CFLog.setCFRowCount(cfdebug_storedproc.RowCount) />
13    <cfset CFLog.setStartTime(cfdebug_storedproc.StartTime) />
14    <cfset CFLog.setCFScript(CGI.SCRIPT_NAME) />
15    <cfset CFLog.setURLString(CGI.QUERY_STRING) />
16    <cfset CFLog.setTemplate(cfdebug_storedproc.Template) />
17    <cfset CFLog.setCFTimeStamp(cfdebug_storedproc.TimeStamp) />
18    <cfset CFLog.setSQLTimeStamp(Now()) />
19    <cfset CFLog.setType(cfdebug_storedproc.Type) />
20
21    <cfset CFLogger.save(CFLog) />
22</cfloop>

That change is for Name. Inexplicably, in successive Stored Procedure calls in my template, the query output name remained the same for the following Stored Procs, ignoring the actual name. I had to dig down into the result column output to get the correct name for the Stored Procedure called.

view plain print about
1<cfset CFLog.setName(cfdebug_storedproc.result[cfdebug_storedproc.currentRow][1].name) />

If you pull a <cfdump> on the query output, you'll readily see from where this came, and possibly the situation in to which I ran.

Here is the entire chunk of code for my logging template. I'll not provide the Illudium PU-36 generated bean and DAO unless there are some requests. It's easy enough to generate your own.

view plain print about
1<!--- Get the Debugger Service --->
2<cfset factory = createObject("java","coldfusion.server.ServiceFactory") />
3<cfset queries = factory.getDebuggingService().getDebugger().getData() />
4
5<!--- Set up Logging Service - call it once and reuse it --->
6<cfset CFLog = createObject("component","optimization.cfc.Optimization_Code_Log").init() />
7<cfset CFLogger = createObject("component","optimization.cfc.Optimization_Code_LogDAO").init(application.sqlSource) />
8
9<!--- Unique ID per request --->
10<cfset RequestID = Val(Replace(Rand(),"0.","")) />
11
12<!--- EVENT: SQL Queries --->
13<cftry>
14    <cfquery dbType="query" name="cfdebug_queries" debug="false">
15        SELECT *, (endTime - startTime) AS executionTime
16        FROM queries
17        WHERE type = 'SqlQuery'
18    </cfquery>
19    <cfscript>
20        if( cfdebug_queries.recordCount eq 1 and not len(trim(cfdebug_queries.executionTime)) )
21        {
22            querySetCell(cfdebug_queries, "executionTime", "0", 1);
23        }
24    
</cfscript>
25    <cfcatch type="Any">
26        <cfscript>
27            cfdebug_queries = queryNew('ATTRIBUTES, BODY, CACHEDQUERY, CATEGORY, DATASOURCE, ENDTIME, EXECUTIONTIME, LINE, MESSAGE, NAME, PARENT, PRIORITY, RESULT, ROWCOUNT, STACKTRACE, STARTTIME, TEMPLATE, TIMESTAMP, TYPE, URL, et');
28        
</cfscript>
29    </cfcatch>
30</cftry>
31
32<!--- EVENT: Stored Procedures --->
33<cftry>
34    <cfquery dbType="query" name="cfdebug_storedproc" debug="false">
35        SELECT *, (endTime - startTime) AS executionTime
36        FROM queries
37        WHERE type = 'StoredProcedure'
38    </cfquery>
39    <cfscript>
40        if( cfdebug_storedproc.recordCount eq 1 and not len(trim(cfdebug_storedproc.executionTime)) )
41        {
42            querySetCell(cfdebug_storedproc, "executionTime", "0", 1);
43        }
44    
</cfscript>
45    <cfcatch type="Any">
46        <cfscript>
47            cfdebug_storedproc = queryNew('ATTRIBUTES, BODY, CACHEDQUERY, CATEGORY, DATASOURCE, ENDTIME, EXECUTIONTIME, LINE, MESSAGE, NAME, PARENT, PRIORITY, RESULT, ROWCOUNT, STACKTRACE, STARTTIME, TEMPLATE, TIMESTAMP, TYPE, URL');
48        
</cfscript>
49    </cfcatch>
50</cftry>
51
52<!--- SQL Queries Logging --->
53<cftry>
54    <cfloop query="cfdebug_queries">
55
56        <cfset CFLog.setATTUID(client.ATTUID) />
57        <cfset CFLog.setRequestID(RequestID) />
58        <cfset CFLog.setBody(cfdebug_queries.Body) />
59        <cfset CFLog.setDatasource(cfdebug_queries.Datasource) />
60        <cfset CFLog.setIPAddress(CGI.REMOTE_ADDR) />
61        <cfset CFLog.setEndTime(cfdebug_queries.EndTime) />
62        <cfset CFLog.setExecutionTime(cfdebug_queries.ExecutionTime) />
63        <cfset CFLog.setLine(cfdebug_queries.Line) />
64        <cfset CFLog.setName(cfdebug_queries.Name) />
65        <cfset CFLog.setCFRowCount(cfdebug_queries.RowCount) />
66        <cfset CFLog.setStartTime(cfdebug_queries.StartTime) />
67        <cfset CFLog.setCFScript(CGI.SCRIPT_NAME) />
68        <cfset CFLog.setURLString(CGI.QUERY_STRING) />
69        <cfset CFLog.setTemplate(cfdebug_queries.Template) />
70        <cfset CFLog.setCFTimeStamp(cfdebug_queries.TimeStamp) />
71        <cfset CFLog.setSQLTimeStamp(Now()) />
72        <cfset CFLog.setType(cfdebug_queries.Type) />
73
74        <cfset CFLogger.save(CFLog) />
75    </cfloop>
76    <cfcatch type="Any">
77        <!--- Error reporting query event --->
78    </cfcatch>
79</cftry>
80
81<!--- Stored Procedures Logging --->
82<cftry>
83    <cfloop query="cfdebug_storedproc">
84
85        <cfset CFLog.setATTUID(client.ATTUID) />
86        <cfset CFLog.setRequestID(RequestID) />
87        <cfset CFLog.setBody(cfdebug_storedproc.Body) />
88        <cfset CFLog.setDatasource(cfdebug_storedproc.Datasource) />
89        <cfset CFLog.setIPAddress(CGI.REMOTE_ADDR) />
90        <cfset CFLog.setEndTime(cfdebug_storedproc.EndTime) />
91        <cfset CFLog.setExecutionTime(cfdebug_storedproc.ExecutionTime) />
92        <cfset CFLog.setLine(cfdebug_storedproc.Line) />
93        <cfset CFLog.setName(cfdebug_storedproc.result[cfdebug_storedproc.currentRow][1].name) />
94        <cfset CFLog.setCFRowCount(cfdebug_storedproc.RowCount) />
95        <cfset CFLog.setStartTime(cfdebug_storedproc.StartTime) />
96        <cfset CFLog.setCFScript(CGI.SCRIPT_NAME) />
97        <cfset CFLog.setURLString(CGI.QUERY_STRING) />
98        <cfset CFLog.setTemplate(cfdebug_storedproc.Template) />
99        <cfset CFLog.setCFTimeStamp(cfdebug_storedproc.TimeStamp) />
100        <cfset CFLog.setSQLTimeStamp(Now()) />
101        <cfset CFLog.setType(cfdebug_storedproc.Type) />
102
103        <cfset CFLogger.save(CFLog) />
104    </cfloop>
105    <cfcatch type="Any">
106        <!--- Error reporting query event --->
107    </cfcatch>
108</cftry>

ColdFusion Custom Debugging Template

Build your own ColdFusion Custom Debugging Template

You can create your own ColdFusion custom debugging template. Build it and drop it into your CF web root WEB-INF/debug folder.

In my case on Windows the folder is C:\ColdFusion10\cfusion\wwwroot\WEB-INF\debug

However, it's not so easy to build your own template! You'll have to use the ColdFusion Service Factory explained in this blog post.

The easiest way to start is to take classic.cfm in the debug folder and experiment.

If you don't believe me, believe Ben Forta! Displaying Query Contents In Debug Output

Why would you want to create your own custom debugging template? In my case, I wanted to create a feature that would log actions from a particular template when accessed only by particular users. It's on a shared development server where debugging is normally not utilized, thus no conflicting debugging usage. I dropped in my custom debugging (logging) template, turned on debugging in the CF Admin and added the appropriate IP addresses of the developers we were logging. There are certainly other ways to skin this cat, for example, we could have dropped in the debug/log template into any directory and added a <cfinclude> in the template we were tracking. But, in my particular case, we didn't want to make any changes to existing code.

Next, I'll go into detail on how I created a Custom Debugging template (logging template) utilizing the ColdFusion Service Factory.

Where Does CF Debug Information Come from Mommy? Or How to use the ColdFusion Service Factory

Have you ever wondered where ColdFusion gets the information presented when debugging is turned on in the CF Admin? It comes from the ColdFusion Server's Service Factory. Of the many things that this produces, one is the debugging service.

Drop this code into one of your templates:

view plain print about
1<cfdump var="#createObject("java","coldfusion.server.ServiceFactory").getDebuggingService().getDebugger().getData()#" label="Debug Data" />

You can see first that we are calling the Service Factory, then the Debugging service, then the Debugger, and finally the data produced. If you care to investigate what each does, simply eliminate calls from the right end of the createObject statement and dump it.

Previous Entries / More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.9.7. Contact Blog Owner