Subsonic 3.0 SQLite FormatException parsing DateTime? - subsonic

I have an MS Access database, which I have converted to an SQLite database. I have SubSonic setup and working, and I can pull data out of the database successfully into a WinForms app using ActiveRecord. All except for one table.
I get a FormatException, "String was not recognized as a valid DateTime". The format of the date column in the database is DD/MM/YYYY.
I'm not even trying to do anything too complicated:
var allOrders = order.All();
foreach (order o in allOrders)
{
listBox1.Items.Add(string.Format("{0} - {1}", o.OrderDate.HasValue ? o.OrderDate.Value.ToShortDateString() : string.Empty, o.Product));
}
I'm not exactly sure why the problem is manifesting in the first place :(

SQLite has "interesting" ways of formatting dates - you have to be very, very sure that you're getting back what you think you are because normally it's not DD/MM/YYYY - it's the opposite if I recall.

Related

Forcing a string field to DateTime in WCF query with Azure Table Storage

So, a quick overview of what I'm doing:
We're currently storing events to Azure Table storage from a Node.js cloud service using the "azure-storage" npm module. We're storing our own timestamps for these events in storage (as opposed to using the Azure defined one).
Now, we have coded a generic storage handler script that for the moment just stores all values as strings. To save refactoring this script, I was hoping there would be a way to tweak the query instead.
So, my question is, is it possible to query by datetime where the stored value is not actually a datetime field and instead a string?
My original query included the following:
.where( "_timestamp ge datetime'?'", timestamp );
In the above code I need to somehow have the query treat _timestamp as a datetime instead of a string...
Would something like the following work, or what's the best way to do it?
.where( "datetime _timestamp ge datetime'?'", timestamp );
AFAIK, if the attribute type is String in an Azure Table, you can't convert that to DateTime. Thus you won't be able to use .where( "_timestamp ge datetime'?'", timestamp );
If you're storing your _timestamp in yyyy-MM-ddTHH:mm:ssZ format, then you could simply do a string based query like
.where( "_timestamp ge '?'", timestamp );
and that should work just fine other than the fact that this query is going to do a full table scan and will not be an optimized query. However if you're storing in some other format, you may get different results.

Wrong time format fetched

I am using Node for fetching data from MySQL. In database, i got record like : 2013-08-13 15:44:53 . But when Node fetches from Database , it assigns value like 2013-08-19T07:54:33.000Z.
I just need to get time format as in MySQL table. Btw ( My column format is DateTime in MySQL)
In Node :
connection.query(post, function(error, results, fields) {
userSocket.emit('history :', {
'dataMode': 'history',
msg: results,
});
});
When retrieving it from the database you most likely get a Date object which is exactly what you should work with (strings are only good to display dates, but working on a string representation of a date is nothing you want to do).
If you need a certain string representation, create it based on the data stored in the Date object - or even better, get some library that adds a proper strftime-like method to its prototype.
The best choice for such a library is moment.js which allows you to do this to get the string format you want:
moment('2013-08-19T07:54:33.000Z').format('YYYY-MM-DD hh:mm:ss')
// output (in my case on a system using UTC+2 as its local timezone):
// "2013-08-19 09:54:33"
However, when sending it through a socket (which requires a string representation) it's a good idea to use the default one since you can pass it to the new Date(..) constructor on the client side and get a proper Date object again.

Entity Framework & Oracle: Cannot Insert VARCHAR2 > 1,999 Characters

I created a 4,000-character VARCHAR2 field in an Oracle table. I am inserting string values into the field using LINQ to Entities with Visual Studio 2010, .NET Framework 4, and ODAC 11.2 Release 4 and Oracle Developer Tools for Visual Studio (11.2.0.3.0). When I try to insert a string value greater than 1,999 characters, I get the following inner exception:
Oracle.DataAccess.Client.OracleException
ORA-00932: inconsistent datatypes: expected - got NCLOB
However, I can insert a 4,000 character string value into the field without any issue when doing so using SQL Developer.
There is a known ODAC bug (source #2) in which there is a 2,000 character limit when saving to an XMLTYPE field, but I am not saving to an XMLTYPE field. I have Oracle.DataAccess 2.112.3.0 in my GAC, and I considered updating to release 5 (11.2.0.3.20) of the aforementioned Oracle software, but "Oracle Developer Tools for Visual Studio" is the only component that appears to have been updated from release 4, and I believe that "Oracle Data Provider for .NET 4" is the component that needs updating. In my .NET project, System.Data.Entity and System.Data.OracleClient are both runtime version 4.0.30319.
Anyway, I am just wondering if anyone else has encountered this error, and if so, if any solution has been found - aside from the one in the Oracle forum thread that is linked above that proposes using stored procedures as a workaround. Google tells me that people are encountering this error only when working with XMLTYPE fields, but I can't be the only person who is encountering this error when working with a VARCHAR2 field, can I?
(FWIW, I am also hoping to receive a response to my post as user "997340" in the Oracle forum thread that is linked above. If I receive a useful response, I'll be sure to share the knowledge on this end.)
EDIT: In case it helps, below are the two blocks in my code that are failing. I created the second block when troubleshooting the first, just to see if there was any difference. I get the exception when checking to see if the string values were already inserted (the "if" statements), and when actually inserting the string values (the "AddObject" statements).
1:
if (!(from q in db.MSG_LOG_MESSAGE where q.MESSAGE == msg select q.MESSAGE).Any())
{
db.MSG_LOG_MESSAGE.AddObject(new MSG_LOG_MESSAGE { MESSAGE = msg });
db.SaveChanges();
}
2:
if (!db.MSG_LOG_MESSAGE.Any(q => q.MESSAGE == msg))
{
db.MSG_LOG_MESSAGE.AddObject(new MSG_LOG_MESSAGE { MESSAGE = msg });
db.SaveChanges();
}
APRIL 3 UPDATE:
I was able to trace the SQL that is being sent to Oracle from the "if" statement in the first code block above. Here it is:
SELECT
CASE WHEN ( EXISTS (SELECT
1 AS "C1"
FROM "SEC"."MSG_LOG_MESSAGE" "Extent1"
WHERE ("Extent1"."MESSAGE" = :p__linq__0)
)) THEN 1 WHEN ( NOT EXISTS (SELECT
1 AS "C1"
FROM "SEC"."MSG_LOG_MESSAGE" "Extent2"
WHERE ("Extent2"."MESSAGE" = :p__linq__0)
)) THEN 0 END AS "C1"
FROM ( SELECT 1 FROM DUAL ) "SingleRowTable1" ;
Unfortunately, the DBA that I worked with did not provide me with the value of the "p_linq_0" parameter, but as previously stated, when it is over 1,999 characters, an exception occurs. (When this SQL was traced, I passed a 4,000-character string as the parameter, and of course an exception occurred.) The DBA also mentioned something about certain SQL clients - such as SQLPlus - not being able to handle VARCHAR2s over 2,000 characters. I did not entirely follow. Whether using SQLPlus, SQL Developer, or any other tool, Oracle is still going to be querying a 4,000-character VARCHAR2 field. Plus, my magic number is 1,999 characters; not 2,000 characters. Did the DBA perhaps mean there is a limitation with how many characters can be in a parameter? More importantly, when I execute this SQL in SQL Developer and I enter a 4,000-character string for the parameter, it works perfectly. So I am still utterly confused about why it is not working via LINQ to Entities. I also tried the following code in my program to run a similar query with a 4,000-character string in the "msg" variable, which worked perfectly as well:
using Oracle.DataAccess;
using Oracle.DataAccess.Client;
using System.Data;
...
OracleConnection conn = new OracleConnection("Data Source=[MASKED];User Id=[MASKED];Password=[MASKED]");
conn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT message FROM msg_log_message WHERE message = '" + msg + "'";
cmd.CommandType = CommandType.Text;
OracleDataReader dr = cmd.ExecuteReader();
dr.Read();
string result1 = dr.GetString(0);
conn.Dispose();
For now, I am still pointing fingers at ODAC being buggy as it pertains to LINQ to Entities...
The latest ODP.NET documentation - for "11.2 Release 5 Production (11.2.0.3.0)" from September 2012 - states the following known issue under the "Entity Framework Related Tips, Limitations and Known Issues" section, which addresses the error from the "if" statements in the question's code blocks:
An "ORA-00932 : inconsistent datatypes" error can be encountered if a string of 2,000 or more characters, or a byte array with 4,000 bytes or more in length, is bound in a WHERE clause of a LINQ/ESQL query. The same error can be encountered if an entity property that maps to a BLOB, CLOB, NCLOB, LONG, LONG RAW, XMLTYPE column is used in a WHERE clause of a LINQ/ESQL query.
Older ODP.NET documentation - for "Release 11.2.0.3.0 Production" from May 2011 - states the same known issue, so apparently this has been a known issue for a while.
Neither of the aforementioned documentation mentions encountering the same error from the "AddObject" statements in the question's code blocks, but that issue is very similar to another known issue for XMLType fields that is mentioned:
An "ORA-00932: inconsistent datatypes: expected - got NCLOB" error will be encountered when trying to bind a string that is equal to or greater than 2,000 characters in length to an XMLType column or parameter. [Bug 12630958]

NSPredicate fetch Core Data objects with dates attribute within NSDate date range

I'm using an NSPredicate with a couple of <= constructs to fetch objects from a Core Data store with a startDate attribute between 2 dates but I'm getting 0 objects fetched.
Here's my NSPredicate:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"( ( %# <= %K ) && ( %K <= %# ) )", fromDate, #"startTime", #"startTime", toDate];
Here's the console output:
predicate: CAST(336261600.000000, "NSDate") <= startTime AND startTime <= CAST(339285599.000000, "NSDate")
[sectionInfo numberOfObjects]: 0
Here are the dates that are in Core Data (the Attribute Type is set to Date):
startTime
---------
337249800
337309200
337318200
fromDate and toDate are both NSDate objects. I've tried substituting these with distantPast and distantFuture to make completely sure than my Core Data startTime attributes are within the date range and I still get 0 object fetched.
I have no idea why 0 objects are returned. Can anyone see where I'm going wrong?
I'd start by adding the following executable argument:
-com.apple.CoreData.SQLDebug 1
This is going to spew a gigajazillion lines of debugging information to the console when you run your app, but it should also include information about the predicate its attempting to translate to SQL, and perhaps even why it's not working.
You'll obviously want to turn remove this before shipping your app :)
After looking at the generated SQL queries it appeared like the TIMESTAMP was being evaluated as a string and not an integer. This explained why my predicate wasn't working. I confirmed this by running the following SQL query on the SQLite db that I'm using to pre-populate Core Data.
SELECT DISTINCT typeof(ZSTARTTIME) FROM ZMATCH;
This showed that the TIMESTAMP field was of type BLOB!
Adding '+0' to my predicate so the startTime attribute was evaluated as an integer fixed the issue. However this seemed like a nasty solution. Also keeping the dates stored as blobs would most likely cause issues further down the road. So I went back and re-populated the the SQLite db from scratch making sure the TIMESTAMPs were inserted as integers and not strings. Now everything is working fine.
However this does mean that I'm going to have to do some more work with the next app update because I'll have to make sure the update overwrite the old SQLite db in the Documents folder with the new db. Is there a easy way to do this? Should I look at Core Data store migration??

SubSonic SQL CE Error

I have an old c# project which currently runs on a SQL CE database. I decided yesterday that I would like to use SubSonic to generate a DAL for me as I have used SubSonic a lot in my other projects (with a standard MS SQL database backend) and I love it's ease of use.
Everything seems fine, I can create and delete records but as soon as I update a record using the Save() method an error it thrown:
Example:
Person person = new Person();
person.Name = "Robert";
person.Save(); // Works fine, record is saved
person.Name = "Robert - Updated";
person.Save(); // Fails with error below
"There was an error parsing the query. [ Token line number = 1, Token line offset = 61, Token in error = SELECT ]"
When I update a record by creating a new Query and setting the QueryType to Update, it also seems to be working as expected.
Any ideas?
Thanks
Try to get hold of the generated SQL to see what gets executed.
My guess is that SubSonic escapes column or table names with [ and ], which is fine for a full-blown SQL Server, but its CE counterpart does not support that.
My guess is that Subsonic is trying to execute several SQL statments in a single command - this is not supported by SQL Compact

Resources