sqlite throwing a "String not recognized as a valid datetime" - c#

I am playing around with Sqlite and keep getting an error when trying to read back some test data. For example, I created a simple db with a single table and some columns and populated it with some test data as shown below.
sqlite> .schema
CREATE TABLE "shows"(id integer primary key asc autoincrement, showName TEXT, guest TEXT, dateAired date, dateWatched date);
sqlite> select * from shows;
6|test show|test guest 1|2012.05.01|2012.07.10
7|test show|test guest 2|2012.05.02|2012.07.10
8|test show|test guest 4|2012.05.04|2012.07.10
I am using the System.Data.Sqlite library available here , but it keeps giving me an error while trying to read the date column. I tried putting the dates in the dd-MM-yyyy format, but still get an error saying "String Not Recognized as a valid datetime." I have tried using DateTime.Parse or casting it to datetime or just ToString()'ing it to see what happens, but I keep getting the same error. I can read the text fields fine, but can't read the date fields.
My C# code snipped is given below
var sqliteConn = new SQLiteConnection("Data Source=data/shows.db;Version=3;New=False;Compress=True");
sqliteConn.Open();
SQLiteCommand cmd = new SQLiteCommand(sqliteConn);
cmd.CommandText = "select * from shows";
SQLiteDataReader reader = cmd.ExecuteReader( );
while (reader.Read( ))
{
var showName = reader["showName"];
// This is where it keeps giving me an error.
// I have tried various things such as DateTime.Parse
var airedDate = DateTime.ParseExact("yyyy.MM.dd", reader["dateAired"].ToString(), new CultureInfo("en-AU"));
}
reader.Close( );
Any help would be greatly appreciated.
Regards,

Based on the discussion in this thread, I decided to construct my connection string with the "datetimeformat" parameter and the "String Not Recognized as a valid datetime" issue was resolved.
My example connection string:
source=<source to db file>;version=3;new=False;datetimeformat=CurrentCulture
This feature was released in version 1.0.87.0 on July 8, 2013 (see release notes)

This thread might be a bit old but I came across the same problem and found a "solution".
It seems that System.Data.SQLite does not handle DateTimes correctly. I tried DateTime.ParseExact and gave the format in my database (mm/dd/yyyy) but I noticed that it threw an error when just calling ToString() on the DataReader column for the date. This seemed strange since I was not attempting to fit it into a Date but have it read out as a String.
Because of this, I went back to the view I was calling from the database and wrapped all of my dates in a CAST as nvarchar(10). This way, the database will return strings and not dates. Now, the DateTime.Parse works just fine!
I'll use a trigger on the view to pull the string/date back in and insert/update the underlying tables, thus having all the conversions happen in the database, instead of System.Data.SQLite.
There is a new version of System.Data.SQLite coming sometime in December of 2012, I hope this is addressed!

select strftime('%m/%d/%Y',substr(colName,0,20)) from tablename
This will work, I have tested this, because built in functions in sqlite converts string to datetime format

Changing the string for connection didn't work for me but the trigger idea help me use it this way
"Select Cast("Coulname" as nvarchar(20)) From "Table Name"

Error "String was not recognized as a valid DateTime."
Change your system date time format to you database fild datetime format.
i hope it help you....

Related

Insert empty DateTime from C# into FoxPro

I am trying to insert an empty DateTime into a FoxPro database using DbParameter in C#. Our application marries FoxPro data along with SQL Server and .NET models/data.
My current issue is that most of our DateTime types in C# are not nullable, nor should they be. However, most of our legacy data in FoxPro are empty dates (shown as ' / / : : '). I am trying to do an insert into the FoxPro table where I do a check to see if the .NET DateTime meets certain criteria, then inserts an empty date. This last part has proven to be a nightmare.
What I have tried so far:
.Parameters.Add(string.Empty, new DateTime())
The above understandably inserts 01/01/0001 but is not what we want.
.Parameters.Add(string.Empty, "{}")
.Parameters.Add(string.Empty, "{:://}")
.Parameters.Add(string.Empty, "{//}")
.Parameters.Add(string.Empty, "'{}'")
The above all result in
System.Data.OleDb.OleDbException: 'Data type mismatch'.
which makes sense because I'm trying to send a string to a field with DateTime type.
Does anyone know how to insert an empty DateTime into FoxPro?
If I'm understanding you correctly, you're not using a DbParameter, but rather an OleDbParameter, and you're adding them through the OleDbParameterCollection.Add method?
If so, consider that you are using the overload that is .Add(String, Object), and you could instead use the overload that is .Add(String, OleDbType):
.Parameters.Add(string.Empty, OleDbType.Date)
The default value of an OleDbParameter is null, so you don't need to do anything more for your empty dates.
Also, depending on how the column is defined in your FoxPro database schema, it may be appropriate to pass OleDbType.Date, OleDbType.DBDate, OleDbType.DBTime, or OleDbType.DBTimeStamp. The full list of OleDB types is documented here, but I'm not entirely certain how they align to FoxPro's data types.
I believe your second example is close, but you have the Date and Time portions reversed.
It should be .Parameters.Add(string.Empty, "{//::}")
The // represent the Date portion, and the :: the Time portion.
Not sure of your SQL-Insert statement for VFP, but you MAY need to adjust it and do TWO different inserts. One IF a date exists, another if it does not.
For the one that does NOT have a date, I would hard-enter the following (for example where the "?" are the parameter place-holders)
insert into yourTable ( fld1, fld2,..., YourDateField ) values ( ?, ?, ..., ctot('') )
the function CTOT() means character to datetime and an empty string will comply with expected VFP Date/time field.
Work for me.
Parameters.AddWithValue("CreateDate", new DateTime(1899,12,30,0,0,0));

Datetime format is 'mm-dd-yyyy' when getting while using SqlDataAdapter but if I run the same query in ms sql then its 'yyyy-mm-dd'

I know the question is a bit confusing. Please let me elaborate.
Suppose
I have a table student master which has a column DOB
I have inserted a record and in DOB I have inserted '1991-01-01'
running select statement from sql server is returning date in the same format as it is inserted '1991-01-01' but when I am running the same query from C# using SqlDataAdapter then its returning date as '01-01-1991'
Can anyone explain why it is happening and is there any way to fetch the date in same format as it is inserted.
Query
Is it possible to get the DateTime using SqlDataAdapter as it was inserted?
P.S: column data type is Datetime
let's separate the wheat from the chaff :)
if for your needs meaningful is data type (datetime in this case), then formatting does not matter at all. All layers which will exchange or process the data will use data type information for that.
But
if the meaningful part is formatting, i.e. string representation of the data, then you need to consider the appropriate settings of UI tools you use to display your data. SSMS, for example, uses regional settings for that. If you need to visualize data in the identical manner, so you need the identical strings, you should take care of formatting by your self or in another words, you need to convert your datetime data to string in the same way in all places where you need it.
In T-SQL, for example, you could use CAST and CONVERT functions for formatting your data in a format you need.
If you can't match up the "Cultures" between the SQL Server and the machine you're building the application on (and, in fact, you cannot rely on that really if you're application is going to be deployed to other machines!), then the cheap and quick way round it is to run your date returns through a parse function such as this:
private string FncFormatDate(string date)
{
DateTime formattedDate;
if (DateTime.TryParse(date, out formattedDate))
{
return formattedDate.ToString("yyyy-MM-dd");
}
else
{
return "Invalid date";
}
}
I hope this answers your question.

Filter out by Date in SQL through c#

Hallo ladies and gentlemen
I have a problem with my sql in C#. So let me make this simple
Here is my code:
OleDbConnection mydb;
OleDbCommand cmd;
OleDbCommandBuilder build;
OleDbDataAdapter adapter;
DataTable dt;
DataSet ds;
BindingSource bs;
String query;
public AnnualRateHistory()
{
InitializeComponent();
query = #"SELECT * FROM _Annual_Rate WHERE Date = 02/11/2014";
build = new OleDbCommandBuilder(adapter);
bs = new BindingSource();
adapter = new OleDbDataAdapter(query, mydb);
dt = new DataTable();
adapter.Fill(dt);
}
Ok I removed a lot of code to make it simple but basically my problem must be at the sql. Code I removed was mydb.Open() and close and the connection as well.
If I use that sql statement nothing shows up and it is set precisely to one of my data in the database. If I replace the '=' with '>' then everything shows up; if I use '<' then nothing shows up. I know that the date should be typed like this: '02/11/2014' but for some reason I get a data type mismatch and also on my other form it works without the '.
I can't find any errors with the SQL. Please tell me what am I doing wrong.
Here is the table schema definition:
And here is the data in the table:
I'm seeing two problems here with your SQL
You're filtering on Date when the Column is actually Date_Of_Rate.
You need to put "#" around your DateTime value in the query.
Your query should function if done like so:
query = #"SELECT * FROM _Annual_Rate WHERE Date_Of_Rate = #02/11/2014#";
Two problems -
Your date is not really in the right format. It's usually best to
use ISO8601 date format (i.e. yyyy-MM-ddTHH:mm:ss)
You're asking the SQL server to return rows where the date is
EXACTLY 02/11/2014, which means midnight on that day. If you want all records from that day then it should be:
SELECT * FROM _Annual_Rate WHERE Date_Of_Rate > '2014-11-02' and Date_Of_Rate < '2014-11-03'
EDIT
Having seen your updates to the question, part 2 no longer really applies as it looks like you're only storing dates in the Date_Of_Rate date time field.
HOWEVER part 1 still applies. Dates should always be written in ISO8601 format when talking to SQL DB's.
2/11/2014
means 2nd of November here in the UK, but in the US it means 11th of Feb. Many countries use different date formats and you can't always guarantee the way the server has been set up even in your own country. This has caused us (the company I work for) major headaches in the past. Before switching to ISO8601 dates, we specified dates to be written:
'dd-MMM-yyyy HH:mm:ss' (11-feb-2014 14:19:56)
which worked for a quite a while until a french company supplied a machine with an SQL server setup in french. Feb is Fév in french so all the software that comumicated with that machine bombed out. From then on we learnt our lesson. Always use ISO8601 date formats. They're the only way of getting totally un-ambiguous dates.
Looking at the schema, the problem seems to be that you are simply using the wrong column name - your column is called Date_Of_Rate but you are filtering on a column called Date.
Also Date is a keyword which is probably why you are getting the data mismatch error.
So just changing it to this should fix it:
query = #"SELECT * FROM _Annual_Rate WHERE Date_Of_Rate = '02/11/2014'";
NOTE: Syntax applies to MySQL / SQL Server as question was initially tagged incorrectly.

Error when trying to update values in database

I have the following c#/Query:
TrackDuration =TimeSpan.Parse( Request.Form["TrackDuration"].ToString());
string InsertQuery = string.Format("UPDATE tblTracks SET TrackLength={0}, TrackDuration='{1}', TrackName='{2}',TrackDescription='{3}',TrackMap='{4}',DifficultLevel={5},OverallHeight={6},IsCircular='{7}', ForBeginners='{8}',StartPoint='{9}',ParkingPlace='{10}',SeasonOfYear={11},TrackLocation={12}, Images='{13}' WHERE UserID={14}",
TrackLength, TrackDuration, TrackName, TrackDescription, TrackMap, DifficultID, OverallHeight, IsCircular, ForBeginners, StartPoint, ParkingPlace, SeasonID, AreaID, ImageList, UserID);
But I got this error message:
Syntax error in UPDATE statement
Syntax error (missing operator) in query expression
I realy tried to solve this, but I can't.
How can I fix this problem?
Update:
This is the value of the Query:
UPDATE tblTracks SET TrackLength=35, TrackDuration='02:30:00', TrackName='45',TrackDescription='<p>sometext.</p>
',TrackMap='f',DifficultLevel=3,OverallHeight=450,IsCircular='true', ForBeginners='false',StartPoint='<p>קיבוץיסעור </p>
',ParkingPlace='<p>כניסה לקיבוץ יסעור</p>
',SeasonOfYear=1,TrackLocation=3, Images='' WHERE UserID=1
The sql values types are:
TrackLength = number ; TrackDuration = date/time ; TrackName= string ;TrackDescription= string; TrackMap = string; DifficultLevel=number;OverallHeight=number;IsCircular=true/false;ForBeginners=true/false;
StartPoint=string; ParkingPlace=string; SeasonOfYear=number; TrackLocation=number;Images=string
'02:30:00' is not a correct value for datetime DB field, AFAIK. The default format is controlled by date format setting.
Additionally, '20130412' should work in any case, but for datetime field. You need to format the TrackDuration correctly or use CAST/CONVERT. As TimeSpan doesn't contain date part (it represents a duration and not a point in time), you can only make it up (e.g. prepend "20100101") but that is an awful hack.
The proper solution is to use the correct DB field type.
'02:30:00' might work if the field was of time type. Please read some more about time types in SQL Server.
Even better, why don't you use plain integer for the duration in seconds? The duration is not a date anyway.
The much bigger issue is that you are concatenating strings to set the command text, which opens you for SQL injection attack. If I name the racing track a';DROP TABLE tblTracks;-- your database is toast:
UPDATE tblTracks SET TrackLength=35,
TrackDuration='02:30:00',
TrackName='a';DROP TABLE tblTracks;-- ...

Query problem - rows are returned when query is run in sql navigator , but not in my c# program

Update:
This is the query from the debugger, which was retrieved from a string builder:
{SELECT * FROM FCR.V_REPORT WHERE DATE BETWEEN to_date('14/09/2001' , 'dd/mm/yyyy') AND to_date('30/09/2011' , 'dd/mm/yyyy')}
If you remove the curly brackets and post it in Navigator, it works.
Original:
I have a problem when running my program. The query in sql navigator returns 192 rows but when I run the query on c#(visual studio 2010) the query returns 0 rows.
Below is my c# code:
public static DataTable GetReport(string date1, string date2)
{
DatabaseAdapter dba = DatabaseAdapter.GetInstance();
string SqlQuery =
string.Format(#"SELECT *
FROM FCR.V_REPORT
WHERE DATE BETWEEN to_date('{0}' , 'dd/mm/yyyy')
AND to_date('{1}' , 'dd/mm/yyyy')", date1, date2);
OracleDataReader reader = dba.QueryDatabase(SqlQuery);
DataTable dt = new DataTable();
dt.Load(reader);
int temp = dt.Rows.Count;
return dt;
}
This is the query I am using in sql navigator(which returns 192 rows):
SELECT *
FROM FCR.V_REPORT
WHERE DATE BETWEEN to_date('01/01/2001' , 'dd/mm/yyyy')
AND to_date('30/09/2011' , 'dd/mm/yyyy')
I bet you that the dates passed in from your c# program are different because your sql statement is identical. Put a break point and verify that the dates are exactly the same. Also verify that date1 and date2 are passed in in the appropriate order.
Try dropping the view and create again. Make sure you got the aliases correct too.
When addressing this kind of problem it's usually best to not make too many assumptions in regard to where the error is originating from. If you have access to the box I would run a trace and make sure that the statements being run are indeed identical. If they are identical then you know you have a programmatic error on the receiving or processing side of your application.
You can modify your statement to insert the results into a temporary table and verify that the 192 rows you expect are there. If you are executing the exact same statement and the temp table shows that you are getting the results you expect you've further narrowed down the problem and can begin looking for application errors.
Assuming that your C# code is sending the correct query to the database, there are several ways for Oracle to run the same query differently depending on the session. You may need to get a DBA involved to figure this out (e.g. by looking at the actual executed statement in v$sql), or at least to rule out these weird cases.
NLS_DATE_FORMAT
If the DATE column is stored as a string, there would be an implicit conversion to a date. If SQL Navigator uses a different NLS_DATE_FORMAT than C# the conversion could create different dates. Although if they were different there's a good chance you'd get an error, not just 0 rows.
Virtual Private Database
VPD can add a predicate to every query, possibly using different session information. For example if the program that created the session is like '%Navigator%' it could add 'where 1 = 0' to every query. (I know this sounds crazy, but I've seen something very similar.)
Advanced Query Rewrite
This is meant for materialized views. But some people use it for performance fixes, sort of like stored outlines. And some evil people use it to rewrite your query into a completely different query. Different session settings, such as QUERY_REWRITE_INTEGRITY and CURSOR_SHARING, could explain why the query works on one session but not another. Speaking of CURSOR_SHARING, that may lead to some rare problems if it is set to SIMILAR or FORCE.
I have run into the same situation quite often with other development tools and SQL Server. In my case I found that in the query tool I would have two outputs, the records in a datagrid and the 'rows affected' message in a results pane. However, in my development IDE I would see no data (unless I checked for additional datasets). For some reason it would return the rows affected as the 1st result set. When I turned off the rowcount option in the query itself, then the data showed up in both places.
You could also use a protocol analyzer (e.g., Ethereal) and capture the TCP/IP traffic to verify that the requests are identical over wire. That has helped me in a pinch too.
Best of luck.
jl
I'm wondering is this is the same problem as your question here.
Your string.Format call is not specifying the format of your date1 and date2 values in the SQL string itself. Hence it is using the default DateTime.ToString() of date1 and date2, which could be something like '16/09/2011 12:23:34' and so which does not match the format specified in your to_date statement.
Try this:
string SqlQuery = string.Format(#"SELECT * FROM V_REPORT WHERE DATE BETWEEN
to_date('{0:dd/MM/yyyy}' , 'dd/mm/yyyy')
AND
to_date('{1:dd/MM/yyyy}' , 'dd/mm/yyyy')",
date1,
date2);

Categories

Resources