Filling a DataSet which contains a DateTime column with Sqlite Databases - c#

I am working on a C# WPF project which uses an SQLite database. I am trying retrieving the data from a table within the sqlite database and add to a data set so I can add the data set to the items source of the data grid. One of the columns is a DateTime column but I am getting the following error:
String was not recognized as a valid DateTime.
Below is how I am retrieving the data
private DataSet getAlarmsForSqlite()
{
DataSet ds = new DataSet();
try
{
using (ConnectSQLiteDatabase db = new ConnectSQLiteDatabase(dbPassword))
{
string query = "SELECT * FROM alarms ORDER BY date";
SQLiteDataAdapter da = new SQLiteDataAdapter(query, db.conn);
da.Fill(ds);
}
}
catch (SQLiteException ex)
{
Console.WriteLine("Failed to get alarms. Sqlite Error: {0}", ex.Message);
return null;
}
return ds;
}
And below is the create statement for the table
CREATE TABLE `alarms` (`id` int(11) NOT NULL, `date` datetime NOT NULL,
`type` varchar(50) NOT NULL,
`message` mediumtext NOT NULL,
`level` varchar(45) NOT NULL,
`page` varchar(500) NOT NULL,
`acknowledged` char(1) DEFAULT '0', PRIMARY KEY (`id`))
Thanks for any help you can provide.

try this way
select * from alarms order by date(date) DESC
see the documentation.

There's some discussion regarding this issue here; sqlite throwing a "String not recognized as a valid datetime"
Apparently the SQLite datetime to C# DateTime serialization mapping doesn't exactly work. To me, it sounds like the datetime is coming back as a string so you need to do DateTime.Parse() in your code. In one of the answers to that question it suggests the datetime also needs to be cast to an nvarchar in order for it work.

It is one of two things:
The data in your table is actually in a format which SQLite is not
capable of turning into a datetime. For best results use the
ISO8601 date format "yyyy-MM-dd HH:mm:ss.FFFFFFF". It requires
conversion before writing the data to the database, but is
transparently handled when reading the data back to the dataset.
The ORDER BY term in your query is for some reason preventing the
SQLiteDataAdapter from identifying the correct type for the
column. Even if you order by some other column, the result will be
the same. To avoid the problem, remove the ordering term (which will
then identify the column data type correctly) and sort your DataSet
after it has been filled.
EDIT: After looking into the recommendation of Ramesh, when using the "date" function with the Order By, the behavior outlined in my second point no longer happened.

Related

SQL Server 'Conversion failed when converting date and/or time from character string.' when inserting date values from WinForm DateTimePicker

I'm trying to insert date value from DateTimePicker element in WinForms to a user defined method in the Table Adapter.
This is the function that gets data from the DateTimePicker element and inserts into the user defined method in the Table Adapter.
private void btn_searchRooms_Click(object sender, EventArgs e)
{
string checkIn = dtPicker_checkIn.Value.ToString("yyyy'/'MM'/'dd");
string checkOut = dtPicker_checkOut.Value.ToString("yyyy'/'MM'/'dd");
var dt = roomsTableAdapter.GetAvailableRooms(checkIn, checkOut);
dtGridView_availableRooms.DataSource = dt;
}
This is the user defined method in the Table Adapter that queries data from SQL server.
This is schema of the table that I'm querying data from
The method works fine without an issue but when I insert the date value from DateTimePicker to its parameter , it literally throws "Conversion failed " exception. The format of date is converted to "yyyy/MM/dd" to store it in the table with DATE data type column.
This is db fiddle for more information about the tables and data types that I'm storing db fiddle
How can I send date from C# to SQL Server in "yyyy/MM/dd" format?
Is there any workaround for this kind of issue?
While inserting date, you can use the following:
commmand.Parameters.Add("#Date", SqlDbType.Date).Value = dateTimePicker1.Value.Date;
#Date is a parameter. change it to your parameter name.

Stored procedure with ADO.NET - String or binary data would be truncated

I have an SQL table with the following fields (type in parenthesis)
id (varchar(255)) primary key
dateStarted (date)
dateFirstPayement (date)
amount (decimal)
numberPayments (int)
telNum (varchar(20)) foreign key
VIN (varchar(255)) foreign key
None of these accept NULL.
I am trying to insert some values from a C# program, here is how I get the values from the WPF form.
id
string id = textBox_id.Text;
startingDate, firstPaymentDate
DateTime startDate = Convert.ToDateTime(datePicker_startDate1.SelectedDate);
DateTime dateFirstP= Convert.ToDateTime(datePicker_firstP.SelectedDate);
telNum, NIV
string telNum = comboBox_telNum.SelectedValue.ToString();
string VIN = comboBox_VIM.SelectedValue.ToString();
amount, numberPayments
Decimal amount = Convert.ToDecimal(textBox_amount.Text);
int numberPayments = Convert.ToInt32(textBox_numberPayment.Text);
Here is my C# code to execute the stored procedure that inserts the values :
SqlConnection connection = new SqlConnection();
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.DataSource = "D106213";
builder.InitialCatalog = "ML645";
builder.IntegratedSecurity = true;
connection.ConnectionString = builder.ConnectionString;
connection.Open();
SqlCommand newLocation = new SqlCommand("nouvelleLocation", connection);
newLocation.CommandType = CommandType.StoredProcedure;
newLocation.Parameters.AddWithValue("#idLocation", id);
newLocation.Parameters.AddWithValue("#dateDebut", startDate);
newLocation.Parameters.AddWithValue("#datePremierPaiement", dateFirstP);
newLocation.Parameters.AddWithValue("#montantPremierPaiement", amount);
newLocation.Parameters.AddWithValue("#nombrePaiement", numberPayments);
newLocation.Parameters.AddWithValue("#numTel", telNum);
newLocation.Parameters.AddWithValue("#NIV", VIN);
newLocation.ExecuteNonQuery();
This is the error that I get when I try to insert the information through my WPF form:
System.Data.SqlClient.SqlException (0x80131904): String or binary data would be truncated
The code to connect to the database is fine, as it's working for all my other procedures using the same ConnectionString. I didn't post it all for clarity purposes, but it is wrapper in a try/catch block to handle the exceptions.
What I assume is that the data types in SQL and C# are not equivalent and one of them is causing a problem. I'm certain that the size of the data (ex: strings) is not exceeding the maximum lenght defined in SQL.
Sorry for the messy text formatting, I'm new to using StackOverflow and I didn't get the hang of it yet.
Thank you all very much for your help, and have a nice day.
EDIT
It is now fixed. My problem was that in the stored procedure, I inversed/swapped two values (telNum and VIN) so it was trying to insert the VIN value in the telNum column. The telNum only accepted VARCHAR(20) initially, and the VIN was 23 caracters long ..
I almost missed it, I originally changed the data types to VARCHAR(50) for the telNum (and thus I didn't had the error), but then I realized something was wrong when I was getting a foreign key error.
Thank you for your great help, it's extremely appreciated.
The problem is either with the input parameter datatypes to the Stored Procedure (hard to tell without the proc signature being posted) or possibly with the adding of the values to the SqlParameterCollection in C#.
The first thing to check is that the 3 string fields:
id (varchar(255))
telNum (varchar(20))
VIN (varchar(255))
are defined with the same max length between the table and the Stored Procedure. One technical nuance with SQL Server Stored Procedures that is being overlooked is that they silently truncate values. This means that as long as the max lengths (and all of the datatypes, really) match between the table and the input parameters, it is not possible to get a "String or binary data would be truncated" error (unless you are manipulating the values after they come into the proc but before the INSERT / UPDATE statement).
If those all match then the problem cannot be the procedure. The next thing to check is the use of the AddWithValue method of the SqlParameterCollection. I recall reading somewhere that it doesn't always work as expected in terms of string lengths. Try changing those 3 fields to straight Add calls passing in new SqlParameter("#idLocation", SqlDbType.VarChar, 255) where you can specify the exact max length of each field.
I would use the SQL Profiler to see exactly the data being passed to the stored procedure. Otherwise it's hard to know which variable is exceeding the expected parameter.

Custom field in SQLite SELECT query doesn't become DateTime column in DataTable after filling it

I have a field declared as datetime in the CREATE TABLE query, I call this field BirthDay, if I have the following query and fill in a DataTable like this:
SQLiteDataAdapter da = new SQLiteDataAdapter("SELECT BirthDay FROM myTable", myConnection);
DataTable dt = new DataTable();
da.Fill(dt);
myDataGridView.DataSource = dt;
The column BirthDay of myDataGridView has type of DateTime and I can check this via myDataGridView.Columns["BirthDay"].ValueType.
However if I change the SELECT query a little like this:
SQLiteDataAdapter da = new SQLiteDataAdapter("SELECT CASE WHEN 1 THEN BirthDay END AS BirthDay2 FROM myTable", myConnection);
I expected the BirthDay2 column is also type of DateTime after filling in my DataTable and bind to myDataGridView. However the type is System.Object?
I've tried with CAST(... as DATETIME) but the returned type is System.Int64 (I understand that DATETIME in SQLite in fact corresponds to Int64 in .NET), I wonder how I could make it return System.DateTime as the original column BirthDay.
I need the final type (can be checked via DataGridViewColumn.ValueType) is DateTime so that I can use DataGridViewColumn.Format to format my datetime string as what I want.
Our team at work have been researching this issue for a long time. Our final conclusion is that any expression wrapping source field makes source data type unavailable. For ADO.NET providers using of expressions leads to System.Object final type, for ODBC provider it leads to System.String type. So it completely depends on data provider you use. Why does it behave in such way is a question to data provider developers (I haven't found the answer).
By the way, .NET Framework provides a variety of tools to test whether given value is of type expected. There are only 5 basic data types in SQLite 3 (NULL, INTEGER, REAL, TEXT, BLOB). So in .NET code you can pass your value through the test for 3 most common types (INTEGER, REAL, TEXT).

How to insert datetime property from asp.net c# to a date column in sql server?

I have a problem using the calender control .. I am getting the date in a textbox... and I have to insert this into the database .. using asp.net with c#
In my web application the field property is set to datetime and in the table the column's datatype is date..
How can I do this??
The error I am getting is:
The conversion of a varchar data type to a datetime data type resulted
in an out-of-range value. The statement has been terminated.
Could anyone help me in this regard?
Thanks in advance
The error i am getting is: The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
It sounds like you're trying to insert it as a string, which is a generally bad idea. You should use parameterized SQL and set the value as a parameter, still as a .NET DateTime. See the docs for SqlCommand.Parameters for an example of parameterized SQL. You should always keep data in its natural type for as long as possible.
Of course, it's then still possible that you'll get this error if you try to insert a DateTime value which is out of the range that SQL can store. In particular, I believe SQL has a lower limit of 1753 as the year. If your value is DateTime.MinValue for some reason (January 1st, 1AD) then you'd still get this problem. Have you added diagnostics for the value you're trying to insert?
Sorry, my first answer missed your question. Try adding the parameter by doing using the standard parameter system.
command.CommandText = "INSERT INTO FooTable (FooDate) VALUES (#FooDate)";
command.Parameters.AddWithValue("#FooDate", DateToUse.Date);
Using the .Date will only return the date part of the object. Here's another reference to it Date vs DateTime
If you're using a parametrized query, I have no trouble whatsoever to insert that DateTime from the ASP.NET calendar control into a SQL Server database table that contains a column of type DATE.
Use something like this:
// define INSERT statement - of course, yours will look quite different!
string insertStmt = "INSERT INTO dbo.DateTest(TheDate) VALUES(#DateValue);";
// set up connection and SqlCommand to do insert
using(SqlConnection conn = new SqlConnection("....your-connection-string-here...."))
using (SqlCommand cmd = new SqlCommand(insertStmt, conn))
{
// add the parameters - the #DateValue - to the SqlCommand object and
// define it's datatype (on the database) and set the value to be stored
cmd.Parameters.Add("#DateValue", SqlDbType.Date).Value = Calendar1.SelectedDate;
// open connection, execute command, close connection
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
Try one thing first, try to insert 01/01/2012 in the column, because that could because of wrong culture.... it could be mm/dd/yyyy or dd/mm/yyyy
try this 01/01/2012 first and see if thats working.
thanks

Storing C# datetime to postgresql TimeStamp

I'm working on an app that stores data in a spreadsheet to a Postgresql database. I'm familiar with C# and .Net but not so well with Postgresql. I'm having trouble storing a DateTime value into a TimeStamp column; I keep getting an error message: Failed to convert parameter value from a DateTime to a Byte[]. Any advice would be appreciated.
string query = "INSERT INTO organizer(organizer_name, contact_name, phone, alt_phone, created_date, last_update) " +
"VALUES('#name', '#contactname', '#phone', '#altphone', '#created', '#updated')";
OdbcCommand cmd = new OdbcCommand(query, con);
cmd.Parameters.Add("#name", OdbcType.VarChar);
cmd.Parameters["#name"].Value = org.Name;
cmd.Parameters.Add("#contactname", OdbcType.VarChar);
cmd.Parameters["#contactname"].Value = org.ContactName;
cmd.Parameters.Add("#phone", OdbcType.VarChar);
cmd.Parameters["#phone"].Value = org.Phone;
cmd.Parameters.Add("#altphone", OdbcType.VarChar);
cmd.Parameters["#altphone"].Value = org.AltPhone;
cmd.Parameters.Add("#created", OdbcType.Timestamp).Value = DateTime.Now;
cmd.Parameters.Add("#updated", OdbcType.Timestamp).Value = DateTime.Now;
con.Open();
cmd.ExecuteNonQuery();
I don't have a PostgreSQL db handy to test with, but I believe that you are seeing this because the OdbcType.Timestamp is actually a byte array, not a time and date. From MSDN:
Timestamp: A stream of binary data (SQL_BINARY). This maps to an Array of type Byte.
This is probably because the timestamp datatype, in SQL Server, 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.
I would try using OdbcType.DateTime, which seems to map to the concept behind PostgreSQL's timestamp.
EDIT:
Here is a useful post which summarizes the mappings between PostgreSQL and .NET.
You've got a few solutions here...I'm going to assume the organizer table has the created_date and last_update as timestamp fields, correct? The silliest answer is to change those to varchar fields. heh.
2 better answers...I'm assuming this is a formatting error where DateTime.Now doesn't return in the format pgsql wants:
Since you are just giving it the current timestamp
you can define your table to default these columns to now() and then not pass values to this column, on an insert the table would just populate that with the default of now().
instead of defining the variable to DateTime.Now and then passing the variable, just send postgres now() and it will populate it in the format it feels right.
And second potential is to format the date into what PG expects as part of the insert statement...I'd need to know what DateTime.Now gives for a value to format it to what pg wants to see. This might be a bit of string manipulation...

Categories