SQLite -> SQLite date formatting issues - sqlite

I am working on migrating my old application data to a new application database. The old SQLite database has a DateTime column called DateOpened. When I look at the old data, I see this value: 2010-09-16 12:00:00
When I query it in my new (UWP) application, the query returns 1/1/0001 12:00:00 AM, which I assume is because that is DateTime.MinValue.
The result in the new database, is a DateOpened value of -62135510400. Is this storing the value in ticks or something like that? Both SQLite databases have that column as a DateTime field, so I'm not really sure why they are being stored differently.
I updated a different row with the value 1/1/2007 from a DatePicker and it is stored in the new database as 1167694105.602.
I don't necessarily mind that the new database stores the dates this way, but I am trying to figure out a way to get them to copy over properly. I tried manually setting the values in the new database, but with a normal date format (i.e. 1/1/2007), the application crashes when trying to read from the database.
Can someone tell me what I'm missing here? It's probably something simple, but I'm stumped.
EDIT
I was able to get it to read the value correctly from the old database by specifying storeDateTimeAsTicks = false. The default value apparently is true, so my new database is storing as ticks, but when trying to read as ticks from string format, it wasn't working, so it would return DateTime.MinValue.

I was able to get it to read the value correctly from the old database by specifying storeDateTimeAsTicks = false. The default value apparently is true, so my new database is storing as ticks, but when trying to read as ticks from string format, it wasn't working, so it would return DateTime.MinValue.

Related

Unparseable Date in Grails Domain Class from SQLite Database

I have a sqlite db (it is the spiceworks db) and I am mapping the tables to grails domain classes. There is a table in particular that is in a datetime format (yyyy-MM-dd HH:mm:ss). An example of such a date in the db for anyone who wants to verify would be: 2015-06-26 15:32:39
I created the domain class and mapped my properties to the columns. Let grails generate the views so that they are default. When I try to get to the index page I get:
URI
/spiceworks/weeklyReportItem
Class
java.text.ParseException
Message
Unparseable date: "2015-06-26 15:32:39" does not match (\p{Nd}++)\Q-\E(\p{Nd}++)\Q-\E(\p{Nd}++)\Q \E(\p{Nd}++)\Q:\E(\p{Nd}++)\Q:\E(\p{Nd}++)\Q.\E(\p{Nd}++)
I've used MSSQL datetimes in the past and have never ran into this issue. In the database, the data type for the problematic column is datetime. Anyone know what's going on?
EDIT: I only have Read permissions on the db and the spiceworks source code isn't open source.
If you look at that regular expression, you'll see it's looking for a ISO8601 timestamp formatted like YYYY-MM-DD HH:mm:SS.SSS - in other words, it needs a decimal seconds, and you're just providing whole seconds.
An easy fix would be to update every existing value in the relevant column by appending '.000' to it, and update the insertion routines to do the same.
If you refer to the sqlite date time functions, there's a %f format specifier for strftime() that can be used to produce fractional seconds that might be helpful if you're building the timestamp directly in an insert query.
In the database, the data type for the problematic column is datetime
Sqlite3 doesn't have a datetime type. The timestamps you're storing are strings. More information.

Updating an SQLite database via an ODBC linked table in Access

I am having an issue with an SQLite database. I am using the SQLite ODBC from http://www.ch-werner.de/sqliteodbc/ Installed the 64-bit version and created the ODBC with these settings:
I open my Access database and link to the datasource. I can open the table, add records, but cannot delete or edit any records. Is there something I need to fix on the ODBC side to allow this? The error I get when I try to delete a record is:
The Microsoft Access database engine stopped the process because you and another user are attempting to change the same data at the same time.
When I edit a record I get:
The record has been changed by another user since you started editing it. If you save the record, you will overwrite the changed the other user made.
Save record is disabled. Only copy to clipboard or drop changes is available.
My initial attempt to recreate your issue was unsuccessful. I used the following on my 32-bit test VM:
Access 2010
SQLite 3.8.2
SQLite ODBC Driver 0.996
I created and populated the test table [tbl1] as documented here. I created an Access linked table and when prompted I chose both columns ([one] and [two]) as the Primary Key. When I opened the linked table in Datasheet View I was able to add, edit, and delete records without incident.
The only difference I can see between my setup and yours (apart from the fact that I am on 32-bit and you are on 64-bit) is that in the ODBC DSN settings I left the Sync.Mode setting at its default value of NORMAL, whereas yours appears to be set to OFF.
Try setting your Sync.Mode to NORMAL and see if that makes a difference.
Edit re: comments
The solution in this case was the following:
One possible workaround would be to create a new SQLite table with all the same columns plus a new INTEGER PRIMARY KEY column which Access will "see" as AutoNumber. You can create a unique index on (what are currently) the first four columns to ensure that they remain unique, but the new new "identity" (ROWID) column is what Access would use to identify rows for CRUD operations.
I had this problem too. I have a table with a primary key on a VARCHAR(30) (TEXT) field.
Adding an INTEGER PRIMARY KEY column didn't help at all. After lots of testing I found the issue was with a DATETIME field I had in the table. I removed the DATETIME field and I was able to update record values in MS-Access datasheet view.
So now any DATETIME fields I need in SQLite, I declare as VARCHAR(19) so they some into Access via ODBC as text. Not perfect but it works. (And of course SQLite doesn't have a real DATETIME field type anyway so TEXT is just fine and will convert OK)
I confirmed it's a number conversion issue. With an empty DATETIME field, I can add a time of 01-01-2014 12:01:02 via Access's datasheet view, if I then look at the value in SQLite the seconds have been rounded off:
sqlite> SELECT three from TEST where FLoc='1020';
2014-01-01 12:01:00.000
SYNCMODE should also be NORMAL not OFF.
Update:
If you have any text fields with a defined length (e.g. foo VARCHAR(10)) and the field contents contains more characters than the field definition (which SQLite allows) MS-Access will also barf when trying to update any of the fields on that row.
I've searched all similar posts as I had a similar issue with SQLite linked via ODBC to Access. I had three tables, two of them allowed edits, but the third didn't. The third one had a DATETIME field and when I changed the data type to a TEXT field in the original SQLite database and relinked to access, I could edit the table. So for me it was confirmed as an issue with the DATETIME field.
After running into this problem, not finding a satisfactory answer, and wasting a lot of time trying other solutions, I eventually discovered that what others have mentioned about DATETIME fields is accurate but another solution exists that lets you keep the proper data type. The SQLite ODBC driver can convert Julian day values into the ODBC SQL_TIMESTAMP / SQL_TYPE_TIMESTAMP types by looking for floating point values in the column, if you have that option enabled in the driver. Storing dates in this manner gives the ODBC timestamp value enough precision to avoid the write conflict error, as well as letting Access see the column as a date/time field.
Even storing sub-second precision in the date string doesn't work, which is possibly a bug in the driver because the resulting TIMESTAMP_STRUCT contains the same values, but the fractional seconds must be lost elsewhere.

Different date types manipulation

I am currently stuck with a database issue where I need to manipulate data using my database inserts. I am currently doing a website with C# ASP.NET on Visual studio 2012 and the database I am using is SQL Management 2008.
Firstly, I currently store my System.Date into a string and store it as a nvarchar datatype in my database. If I would like to perhaps get the latest 10 rows from for example, user= 'x', how should I actually go about doing the SELECT statement to only get the data I specified?
And I currently store information like Date Of Birth using the calander Ajax toolkit so the format the dates are saved in is in month/day/year format. The data is stored into my database as a nvarchar as well. If I want to perhaps calculate the age of user='x' how should I calculate it?
I think Jon's comment about storing the data properly as a datetime is spot on:
Why are you storing it as an nvarchar to start with? It's logically a
date/time, not a string - so store it as a date/time. Get rid of the
string part, and all your formatting problems go away too.
Definitely do that if you can.
If, for some reason, you can't change your database structure, you can use a CAST / CONVERT statement in your ORDER BY clause to get what you want:
SELECT TOP 10 *, CAST(yourDateField AS datetime) AS convertedDate
FROM yourTable
WHERE
user='Some user'
ORDER BY CAST(yourDateField AS datetime) DESC
This assumes that your nvarchar data can be properly converted to a datetime (which it should be if you're using the Ajax Control Toolkit calendar extender).

ASP.NET saving empty date value in SQL Server database with parameters

I have a web forms application which allows to update database columns. One of the database columns is Finish Date which is of date datatype in the SQL Server database.
I use SQL query with parameters and textbox to provide the new value for the finish date.
This is a code which gets me the value of the date from a text box within the grid:
TextBox tFD = (TextBox)grdProjectUpdate.Rows[e.RowIndex].Cells[11].FindControl("proFDTextBox");
then I use a parameter:
cmd.Parameters.Add("#proFD", SqlDbType.Date).Value = tFD.Text.Trim();
to update the value using this SQL statement:
UPDATE PMSprojects SET proFD = #proFD ,...
This solution works fine whenever there is an actual date provided. However, it does not save nulls. If I provide an empty string, it is being converted into 1900-01-01 date, even though the column in the database allows nulls.
How could I solve this issue and save null to the database?
You have to write code around this to handle, and pass DbNull.Value when the value is null.
cmd.Parameters.Add("#proFD", SqlDbType.Date).Value = (tFD.Text.Trim().Length > 0) ? (object)tFD.Text.Trim() : DbNull.Value;

How to add Timestamp value in SQL Server 2005 by using LINQ

My database table have a Timestamp column named as inTime and i am using LINQ for insert, update data in SQL server. Now i want to add the timestamp value in my database but i don't know how to insert?
spaBL.attendance obj = new spaBL.attendance();
obj.FK_employeeId = 1;
obj.inTime =[what to write here??]
inTime is of timestamp type.
Timestamp as in SQL Server Timestamp data type?
;) If I got a cent every time someone did not read the documentation and thought that is a TIME STAMP I would be more rich than bill gates.
Timestamp data time has NO TIME INFORMATION IN IT. It is a running version number, legacy to Sybase SQL Server where SQL Server from Microsoft originated and a totally borked design.
So, no, you CAN NOT SET THAT FIELD, sorry, and it has no usable value except to see whether it changed (then the row was updated).
The documentation is explicitly clear on that, even if some people think reading is maybe a lost art:
http://msdn.microsoft.com/en-us/library/ms182776(v=sql.90).aspx
Is a data type that exposes automatically generated, unique binary
numbers within a database. timestamp is generally used as a mechanism
for version-stamping table rows.
There is no way for you to set it. CHange your LINQ setup to not update this column.
Timestamp values are auto generated by the server on inserts. You should insert rows to the table without supplying a value for the timestamp column. Sql server will then generate the value for the column.
Note the columns of type timestamp does NOT contain values that can be parsed as a DateTime. The idea behind timestamp columns is that they can be used to check if a row has been updated between fetching the row and trying to update the row with new values.
You do not provide values for columns with a Timestamp (Rowversion) data type. SQL Server will provide a value for you automatically (and it won't be a datetime value). Therefore you do not need to be concerned with having Linq To SQL insert a Timestamp value for you. In fact, you cannot do it. SQL Server will do it for you. You can however, retrieve the value of a Timestamp column. I believe the corresponding C# type will be System.Data.Linq.Binary.
How to add Timestamp value in SQL database by using LINQ
hope it helps
You cannot update a timestamp. See here. And indeed, as TomTom indicated, it doesn't contain actual time information.

Resources