Date format error in ColdFusion and mySQL - mysql

I have set up a file that reads an xml file from one database and inserts that data into another. All works well except a strange error on the date format. The date format I need is yyyy-mm-dd. However, the original data is set up as format dd-mm-yyyy.
My code reads and inserts all the data, but when it reads the date field, there is an issue when the day is under 12. It strangely inserts it the other way around.
If a date is 11/10/2014, it pulls it in as 2014/11/10
But, if a date is 13/10/2014, it pulls it in as 2014/10/13 (which is correct and what I need).
If I set the MySQL field type to text or varchar, it inserts the value in the correct order, but of course not in a date format for ColdFusion. So it inserts a date as 11/10/2014, but when I set the same field to type 'date' or even 'date time' format, it inserts it in the correct format '2014-10-11 but with the issue above.
The code I'm currently working with is:
<cfif isDate(arrA[currentField])>
#currentField# = '#LSdateformat(arrA[currentField],"yyyy-mm-dd")#'
<cfelse>
#currentField# = '#arrA[currentField]#'
</cfif>
My second attempt was using the following:
<cfif isDate(arrA[currentField])>
#currentField# = '#ParseDateTime(arrA[currentField],"yyyy-mm-dd")#'
<cfelse>
...
I then receive the following error:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near '1900-01-01 00:00:00'}' , ScheduleReferenceNumber = 'TS8279631'
,' at line 15
On the third attempt, I used:
<cfloop collection="#arrA#" item="currentField">
<cfif currentField NEQ 'TypeDesc'>
<cfif fieldcount NEQ 0>,</cfif>
<cfif currentField eq 'startDate'>
<cfqueryparam cfsqltype="cf_sql_date" value="#currentField#">
<cfelse>
#currentField# = '#arrA[currentField]#'
</cfif>
<cfset fieldCount=fieldCount+1>
</cfif>
</cfloop>
But I then get the error:
The cause of this output exception was that:
coldfusion.runtime.locale.CFLocaleBase$InvalidDateTimeException:
StartDate is an invalid date or time string..
Having also tried:
<cfset DateLocale = "English (UK)">
<cfset DateString = "11/10/2014">
<cfloop collection="#arrA#" item="currentField">
<cfif currentField NEQ 'TypeDesc'>
<cfif fieldcount NEQ 0>,</cfif>
<cfif currentField eq 'startDate'>
<cfqueryparam value="#LSParseDateTime(dateString, dateLocale)#" cfsqltype="cf_sql_timestamp">
<cfelse>
#currentField# = '#arrA[currentField]#'
</cfif>
<cfset fieldCount=fieldCount+1>
</cfif>
</cfloop>
<cfif checkRecord.recordcount neq 0>
WHERE ScheduleReferenceNumber = '#arrA.ScheduleReferenceNumber#'
</cfif>
</cfquery>
I get the following:
Error Executing Database Query.
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near ''2014-10-11 00:00:00.0' , Currency = '' , Tutor = '' ,
CourseLoc' at line 17

You forgot to specify a Locale. When omitted, the LS date functions use the current page's Locale. Sounds like yours is "English (US)". Per U.S. date conventions, month is always first. So the string "11/10/2014" will always be treated as November 10th, not October 11th.
That said, if you are populating a date/time column, you should use cfqueryparam and pass date objects to the database, rather than date strings, which can be misinterpreted, depending on database settings.
One option is to use LSParseDateTime() with an appropriate Locale. Do not use ParseDateTime(). Like most of the standard date functions, it always uses U.S. date rules, and will produce the same wrong results you are getting now.
<cfset DateLocale = "English (UK)">
<cfset DateString = "11/10/2014">
...
<cfquery ...>
INSERT INTO Table ( SomeColumn )
VALUES (
<cfqueryparam value="#LSParseDateTime(dateString, dateLocale)#"
cfsqltype="cf_sql_timestamp">
)
</cfquery>
Also, for validation, be sure to use the LS version of IsDate. Again with the appropriate Locale.
<cfif LSIsDate( dateString, dateLocale )>
....
</cfif>
NB: Keep in mind CF's date functions are notoriously "generous" about what is considered valid. If the format of your date strings can vary, you may want to implement your own date validation.

Assuming your database datatype is date or something similar, you are using an inappropriate function. LSdateformat() converts a date to a string. The function that converts a string to a date is ParseDateTime().
If your date fields are always arriving with the same format, you can hard code the appropriate mask argument of function ParseDateTime(). If they vary, you'll have to use conditional logic to determine the correct mask.
You should also be cautious about using isDate(). It returns true on some unexpected values such as "apr 31". Combining it with ReFind() and len() would be more thorough.

Related

Mysql getting wrong information from information_schema

Writing in Linux/Lucee and Coldfusion/Mysql. I have several databases in my system, with quite a few tables overlapping. I have a program which would add a field to a given table, say Activity, in each database. Of course I don't want to alter a non-existent table, so I am checking to make sure the table is there.
The simplest way would be to go to the database and use "show tables like 'Activity'". To do that in ColdFusion I used the datasource that belongs to that database. However, when I tried that, I got zero tables even when the table is present.
<cfquery name = 'tbl' datasource = '#thedatasource#'>
show tables like 'Activity'
</cfquery>
The record count for this query is zero. Then I tried using the information schema and got better results with this test program:
<cfquery name = 'dblist' datasource = 'Moxart'>
select MoxcoId from Moxco
</cfquery>
<cfloop query = 'dblist'>
<cfoutput>
<cfquery name = 'tbl' datasource = 'Moxart'>
select table_schema,table_name from information_schema.tables
where table_schema = '#MoxcoId#' AND table_name = 'Activity'
</cfquery>
<cfdump var = '#tbl#'>
</cfoutput>
</cfloop>
This gave exactly the right answer. However, when I put the same code into the real program, it keeps returning zero records. The real program is rather long, however most of the beginning consists of picking up info from the previous form . From the line
<cfquery name = 'dblist' datasource = 'Moxart'>
the only difference is the addition of this section because #MoxcoId# is not always the schema name. The variable #mmox# is in this case blank, so doesn't add anything.
<cfif #MoxcoId# EQ 'Moxart'>
<cfset pref = '#mmox#Moxware'>
<cfelse>
<cfset pref = '#mmox##MoxcoId#'>
</cfif>
When I do a dump on the query 'tbl' it shows that zero records were retrieved, even though the code appears to be exactly correct.
I am baffled. There must be something wrong in my code, but I just can't see it. If anyone can suggest something I would appreciate it.

Lucee need duplicate columns in SQL query

Programming in Lucee (Ubuntu, Firefox) and have a query in which I need duplicate columns. In generic SQL run from my terminal this produces exactly what I ask for. It works fine in ColdFusion. But when I run it in Lucee, it refuses to accept the request for the duplicate column.
<cfoutput>
<cfset mylist = "PersonFn, PersonLn, PersonState, PersonLn">
<cfquery name = "betty" datasource = "Moxart">
select #mylist#
from Person
limit 5
</cfquery>
</cfoutput>
When I get the columnlist for this Query, it has only 3 items in it, having eliminated the duplicate column. When I run a report against the output:
<cfset m = 0>
<cfoutput query = "betty">
<cfloop list = #mylist# index = "xxcol">
<cfset m = m + 1>
#betty[xxcol][currentrow]#
<cfif m EQ 4>
<br>
</cfif>
</cfloop>
</cfoutput>
I get this error:
key [ PersonLn] not found in query, columns are [PersonFn,PersonLn,PersonState]
I really, really need that duplicate column. Programming around this would be very difficult and excruciating.
I cannot use an alias, because the actual list is chosen by the user and there is no way to know what he might choose, or how many duplicates I might have. For similar reasons, I cannot reconstruct the data after the query to create the extra columns -- since I don't know what they are.
To be more exact, I probably can do those things, but the amount and complexity of programming is significant -- and all because Lucee just won't do what generic MySql will do.
Can anyone think of a way I can get those duplicate columns back into my output without major programming?
You can't have duplicate columns in sql you have to rename it to field1 and field2 for example.
What you seek violates the Sql standard.

Data truncation: Incorrect datetime value - coldfusion

I'm working on a submission form for events that once completed, goes to a processing page and updates a database.
I have fourteen fields, several are required one of which is the date and time of the event.
During the processing of the form I join the two form entries, date and time before attempting the insert into the database but an error occurs.
Data truncation: Incorrect datetime value
Here is the code elements that are failing:
<cfset insdate = form["date"] & form["time"]>
<cfset new_date = #CREATEODBCDATETIME(insdate)#>
<cfif len(trim("#institle#"))>
<cfquery name="modify">
INSERT INTO table
SET
title = <cfqueryparam
cfsqltype="CF_SQL_LONGVARCHAR"
value="#institle#">,
dateTime = <cfqueryparam
cfsqltype="CF_SQL_LONGVARCHAR"
value="#new_date#">,
location = <cfqueryparam
cfsqltype="CF_SQL_LONGVARCHAR"
value="#inslocation#">,
category = <cfqueryparam
cfsqltype="CF_SQL_SMALLINT"
value="#inscategory#">,
type = <cfqueryparam
cfsqltype="CF_SQL_TINYINT"
value="#instype#">
</cfquery>
</cfif>
I've trimmed the code above to make it shorter and easier to read. If anyone has any ideas what I'm doing wrong, that would be great.
I'm running Coldfusion 8, a mySQL database and the database accepts datetime on the field in question, in a yyyy-mm-dd hh:mm:ss format.
Cheers.
ColdFusion can handle string representations of several datetime formats using cfSqlType="CF_SQL_TIMESTAMP", as already suggested. There is no need to create a date(time) object for the query at all. Just make sure that isDate(yourDateTimeString) returns true for the string (because that's what CF_SQL_TIMESTAMP will assume) and be aware of differences in the locale. (ddmmyyyy and mmddyyyy are two obnoxious formats that will be mixed up by ColdFusion, I guarantee it.)
Just cut to the chase here. Alter your code to:
<!--- create a date object --->
<cfset new_date = CREATEODBCDATETIME(insdate)>
<!--- format for the DB --->
<cfset new_date = dateformat (new_date, 'yyyy-mm-dd') & ' ' & timeformat(new_date,'HH:mm:ss')>
See if that inserts for you. most DBs take a string and implicitly convert to dattime internally.

How to Invoke JSON data as the correct Data Type?

Question: What data type do I use when invoking JSON data from a database using ColdFusion?
Background: My application needs to pull some JSON data from a database and parse the data into an HTML form.
Below is my code so far:
<cftry>
<cfinvoke component="UserData.cfc.data" method="editData" returnvariable="editReturn">
<cfinvokeargument name="formID" value="#URL.dataID#">
</cfinvoke>
<cfset ReBuild = DeserializeJSON(#editReturns#)>
<cfcatch type="Any">
<cfoutput>
<hr>
<h1>Other Error: #cfcatch.Type#</h1>
<ul>
<li><b>Message:</b> #cfcatch.Message#
<li><b>Detail:</b> #cfcatch.Detail#
</ul>
</cfoutput>
<cfset errorCaught = "General Exception">
</cfcatch>
</cftry>
UserData.cfc.data:
<cffunction name="editData" access="public" returntype="any">
<cfargument name="formID" required="yes">
<!--- Select --->
<cfquery name="UserData" datasource="RC">
SELECT Data
FROM USER_Forms
WHERE ID = <cfqueryparam value="#ARGUMENTS.formID#">
</cfquery>
<!-- The information pulled from the database should be a Serialized JSON data. -->
<cfreturn UserData>
</cffunction>
Error Message:
Other Error: Expression
Message: Complex object types cannot be converted to simple values.
Detail: The expression has requested a variable or an intermediate expression result as a simple value. However, the result cannot be converted to a simple value. Simple values are strings, numbers, boolean values, and date/time values. Queries, arrays, and COM objects are examples of complex values.
The most likely cause of the error is that you tried to use a complex value as a simple one. For example, you tried to use a query variable in a cfif tag.
When I added the data to the database I used the following process:
<cfset ForDBInsert = SerializeJSON(formCopy)>
<!-- Then I INSERTED ForDBInsert into the database columnn. -->
Try DeserializeJSON(editReturns.data) - notice I took out the # they are not needed when passing arguments this way. Looks like you are trying to deserialize the entire query object rather than the string itself.

Can I use MySQL "IN" with a list of strings in Coldfusion?

I'm trying to feed a variables into an MySQL query from Coldfusion. My query currently includes:
<cfif Session.app_assign EQ "0">
AND art.iln IN ( #Session.app_ilns# )
<cfelseif Session.app_assign EQ "1">
AND art.marke IN ( "#Session.app_keys#" )
</cfif>
Session.app_ilns will be a list of numbers like so: 1111111111111,2222222222222.... which works fine. Howerver, Session.app_keys will be list of strings, like:
sample_1, sample_2, sample_3
which will produce an error in my script, because of
unknown column "sample_1, sample_2, sample_3" in where clause.
Question:
Is there a way to use MySQL IN with a list of string values or do I need to pre-loop over the variables to add quotation marks. Are there any other ways to get this done?
Thanks!
Try using a cfqueryparam (good practice anyhow) with list="yes"
See this Ben Nadel blog post
Code would look like:
AND art.marke IN ( <cfqueryparam value="#Session.app_keys#" cfsqltype="cf_sql_varchar" list="yes" />)
Got it. I can set list="true" in cfqueryparam. See here