Conversion failed when passing date/time object to SQL - c#

I am trying to add new information to a table, but it is giving me this Conversion failed error when converting date/time from character to string.
Here is part of my code:
try
{
string sp = "add";
comando.CommandType = CommandType.StoredProcedure;
comando.CommandText = sp;
comando.Parameters.Clear();
comando.Parameters.Add(new SqlParameter("#person", SqlDbType.VarChar));
comando.Parameters.Add(new SqlParameter("#reason", SqlDbType.VarChar));
comando.Parameters.Add(new SqlParameter("#information", SqlDbType.VarChar));
comando.Parameters.Add(new SqlParameter("#date", SqlDbType.DateTime));
comando.Parameters[0].Value = obj.person;
comando.Parameters[1].Value = obj.reason;
comando.Parameters[2].Value = obj.information;
comando.Parameters[3].Value = obj.date;
comando.ExecuteNonQuery();
}
catch (Exception exc)
{
throw exc;
}
To get the information of the date I am using obj.date = DateTime.Now; is this correct?

I don't recall how or why sometimes sending a plain date/time object into SQL won't work as we expect it.
The solution is to convert the date/time object to the universal ISO 8601 format: yyyyMMdd HH:mm:ss.fff - which SQL absolutely loves.
Here's a snippet which takes from J W's answer, which is actually demonstrating best practice:
const String UniversalDateTime = "yyyyMMdd HH:mm:ss.fff";
comando.CommandType = CommandType.StoredProcedure;
comando.CommandText = sp;
comando.Parameters.AddWithValue("#person", obj.person);
comando.Parameters.AddWithValue("#reason", obj.reason);
comando.Parameters.AddWithValue("#information", obj.information);
comando.Parameters.AddWithValue("#date", obj.date.ToString(UniversalDateTime));
// assuming connection is already open
comando.ExecuteNonQuery();
Upon SQL receiving the date/time string representation, the value will automatically be converted to SQL's internal date/time value.
PS. I recall also trying the ISO 8601 format using the T as separator: yyyyMMddTHH:mm:ss.fff. Try the version with the space, which worked for me when using the en-US SQL locale and non-en-US locales too.

Alternatively, you can use AddWithValue()
comando.CommandType = CommandType.StoredProcedure;
comando.CommandText = sp;
comando.Parameters.AddWithValue("#person", obj.person);
comando.Parameters.AddWithValue("#reason", obj.reason);
comando.Parameters.AddWithValue("#information", obj.information);
comando.Parameters.AddWithValue("#date", DateTime.Now);
// assuming connection is already open
comando.ExecuteNonQuery();

Related

Which SQL Date format

Which date format does T-SQL use? Does it rely on the system date? How can I be sure that my parameters are passed on correctly regardless of system date format. This question comes because of error:
Error converting data type nvarchar to datetime.
The SQL script in part:
CREATE PROCEDURE [dbo].[sz_pipeline04_pipelUpdte_inventory]
-- Add the parameters for the stored procedure here
#myFixDte datetime,
#doInsert bit
AS
BEGIN
The calling c# code:
public static DataTable GridInventory(string strdProcedureName, DateTime fixDate, bool execInsertYN)
{
DataTable dtbl_inventory = null;
try
{
dtbl_inventory = new DataTable();
using (var conn = new SqlConnection(cls_connRegistry.GetConnStrFull()))
using (var command = new SqlCommand(strdProcedureName, conn)
{
CommandType = CommandType.StoredProcedure
})
{
command.Parameters.Add("#myFixDte", SqlDbType.DateTime).Value = DateTime.Parse(fixDate.ToShortDateString());
command.Parameters.Add("#doInsert", SqlDbType.Bit).Value = execInsertYN;
conn.Open();
SqlDataReader dr = command.ExecuteReader();
dtbl_inventory.Load(dr);
conn.Close();
}
}
catch (Exception datawalile)
{ dtbl_inventory = null; }
return dtbl_inventory;
}
edited question.
The code you've now posted looks correct - except for one thing:
command.Parameters.Add("#myFixDte", SqlDbType.DateTime).Value = DateTime.Parse(fixDate.ToShortDateString());
As I've said in the comments, issues only come up around formatting when you convert to strings. So just do:
command.Parameters.Add("#myFixDte", SqlDbType.DateTime).Value = fixDate;
DateTimes (C#) and datetime (T-SQL) don't have a format. You get formatting issues when you convert them into strings. In their native representation, they're usually just a count of a number of events (ticks, milliseconds, etc) since some fixed point in the past. ADO.Net knows how to convert a DateTime into a SQL Server datetime.
If you have remaining conversion issues, it's in code you've not yet shown. But it will, again, be because you're converting away from the correct data type (datetime) and using strings.
This is not valid DATETIME format DD-MM-YYYY.
You can use CONVERT It in following:
DECLARE #myFixDte DATETIME
SET #myFixDte = CONVERT(DATE, N'30-12-2012', 104)
SELECT #myFixDte
Or you can SET It without converting in other format like YYYY-MM-DD
Try this:
#myFixDte = convert(datetime, '30-12-2012', 105)
And check the link provided by #N.Molderf
SQL Server recognizes one format always in same way, regardless which culture it using, and that format is YYYYMMDD.
So you can always use your dates in format 20120202 or 20151225, and SQL Server will parse that parameter using same mask.
Why you didnt tell as above c# datetime, here is a simple example for you how to solve this problem in your case it will be something like this
DateTime myDateTime = DateTime.Now;
string sqlFormattedDate = myDateTime.ToString("dd-MM-yyyy HH:mm:ss");
or this one
DateTime myDateTime = DateTime.Now;
string sqlFormattedDate = myDateTime.ToString("yyyy-MM-dd HH:mm:ss");
second one is a default

How to extract time from Datetime

Im trying to extract time from Datetime and then converting it into int to add 10 to it and then convert it into Datetime and store in the database. But I keep getting following error:
"String was not recognized as a valid DateTime."
Following is the code:
MySqlConnection conn = new MySqlConnection(connection);
String query = "Select timings from topogen.token_gen order by timings desc limit 0,1;";
MySqlCommand cmd = new MySqlCommand(query, conn);
String location = "";
conn.Open();
MySqlDataReader r = cmd.ExecuteReader();
string timings="";
while( r.Read()){
timings = r["timings"].ToString();}
DateTime time = DateTime.Parse(timings); //error appears here
timings = time.ToString("HH:mm:ss");
time = DateTime.Parse(timings);
long t = time.Ticks;
t += 10;
timings = t.ToString("HH:mm:ss");
TextBox1.Text = timings;
time = DateTime.ParseExact(timings, "HH:mm:ss", null);
this.Location = location;
conn.Close();
Looks like your r["timings"].ToString() generates a string representation that your CurrentCulture does not have a standard date and time format. That's why your DateTime.Parse throws FormatException.
Change your timings column type to datetime type even it doesn't.
Use GetDateTime() method of MySqlDataReader to get it's value as DateTime
MySqlDataReader r = cmd.ExecuteReader();
if(r.Read())
{
DateTime timings = r.GetDateTime(0);
}
Let's look the rest of your code. They have also some mistakes.
long t = time.Ticks;
With this, you will get Ticks of your DateTime which looks like for example; 2,193,385,800,000,000.
t += 10;
With this, you will get 2,193,385,800,000,010 which is okey for now because it is a long and this is just an addition.
timings = t.ToString("HH:mm:ss");
Here a mistake. You try to get string representation of your long which uses NumberFormatInfo of your CurrentCulture. It doesn't even use DateTimeFormatInfo. That's your your timings will be HH:mm:ss as a string. And you will try to parse it as DateTime.ParseExact(timings, "HH:mm:ss", null) which is equal to DateTime.ParseExact("HH:mm:ss", "HH:mm:ss", null). As you can see, this parsing operation will fail.
Consider to changing your logic.

how to convert datetime format

hi i am giving a textbox to user and ajax calender extender to select date in dd/mm/yyyy format after that i am using following function to convert it to mm/dd/yyyy format for inserting in to sql server database but it not work well in one page i got error datetime conversion error and in other i have to enter yyyy/mm/dd format to insert data into database. my code works fine in localhost but in server these errors are coming . my function is
protected string getDate_MDY(string inDate)
{
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-GB");
DateTime dtProjectStartDate = Convert.ToDateTime(inDate);
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
return (Convert.ToDateTime(dtProjectStartDate).ToString("MM/dd/yyyy"));
}
and for inserting i used it like getDate_MDY(txtcreatedate.text);
i just want to insert my correct date in to database by taking dd/mm/yyyy format from text box. . please show me right way to modify it...thanks
Use DateTime.Parse or DateTime.ParseExact instead of changing the current thread culture. Both of these methods have overloads that take a culture to use when parsing the string.
For example:
protected string getDate_MDY(string inDate)
{
DateTime date = DateTime.Parse(inDate, new CultureInfo("en-GB"));
return date.ToString("MM/dd/yyyy", new CultureInfo("en-US"));
}
This isn't the most efficient way to do this (you'd probably want to cache the CultureInfo instances for starters) but it will do what you asked for (ie. convert a date/time string from one culture to another).
However, as someone pointed out in the comments, you shouldn't be passing date strings to a SQL command. Instead, they should be defined as date/time parameters in the SQL command:
using (var connection = new SqlConnection("<your connection string>"))
using (var command = connection.CreateCommand())
{
command.CommandText = "INSERT INTO (sometable) VALUES (#somedatecolumn)";
command.CommandType = CommandType.Text;
var parameter = new SqlParameter("#somedatecolumn", SqlDbType.SmallDateTime);
parameter.Value = <your date/time value>; // a DateTime value, not a string
command.Parameters.Add(parameter);
command.ExecuteNonQuery();
}
It seems that you should only add DateTimeFormatInfo to your Convert.ToDateTime(inDate) --> Convert.ToDateTime(inDate, DateTimeFormatInfo)
System.Globalization.DateTimeFormatInfo dtfi = null;
DateTime dtProjectStartDate = new DateTime(2008, 4, 10); //year, month, day
ci = System.Globalization.CultureInfo.CreateSpecificCulture("en-GB");
dtfi = ci.DateTimeFormat;
txtBox.Text = dtProjectStartDate.ToString("d", dtfi); // 10/4/2008
System.Globalization.CultureInfo ciForSQL = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
System.Globalization.DateTimeFormatInfo dtfiForSQL = ciForSQL.DateTimeFormat;
DateTime dtForSQL = Convert.ToDateTime(txtBox.Text, dtfiForSQL);
txtBoxForSQL.Text = dtForSQL.ToString("d", dtfiForSQL); // 10/4/2008
Use..DateTime.ParseExact
DateTime.ParseExact("12/02/21 10:56:09", "yy/MM/dd HH:mm:ss",
CultureInfo.InvariantCulture
).ToString("MM/dd/yyyy");

Conversion failed when converting date and /or time from character string

Error is appearing in date_to and date_from while adding data into the database.
In sql server database the data type for date_to & date_from are date. suggest some solution.
try
{
cmd = new SqlCommand("insert into license1 values(#l_id,#customer_id,#d_id,#device_name,#from,#to)", cn);
cmd.Parameters.AddWithValue("#l_id", license_id.Text);
cmd.Parameters.AddWithValue("#customer_id", c_comboBox4.Text);
cmd.Parameters.AddWithValue("#d_id", d_id_comboBox4.Text);
cmd.Parameters.AddWithValue("#device_name", d_name_comboBox5.Text);
cmd.Parameters.AddWithValue("#to", date_to.Text);
cmd.Parameters.AddWithValue("#from", date_from.Text);
cn.Open();
a = cmd.ExecuteNonQuery();
if (a > 0)
{
MessageBox.Show("Data Submitted");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Take the conversion into your own hands:
cmd.Parameters.AddWithValue("#to", DateTime.Parse( date_to.Text));
cmd.Parameters.AddWithValue("#from", DateTime.Parse( date_from.Text));
and when that still fails, use a version of DateTime.ParseExact() with an appropriate Format and CultureInfo.
You might want to consider adding a more robust and extensive validation layer. Dates and numbers are very sensitive to typing errors, User settings and User assumptions.
Always assume TextBox.Text is full of errors.
if user enters the Date Format as: yyyy-MM-dd then try this:
String strDateFormat= "yyyy-MM-dd";//change accordingly if format is something different
DateTime to=DateTime.ParseExact(date_to.Text,strDateFormat, CultureInfo.InvariantCulture);
DateTime from=DateTime.ParseExact(date_from.Text, strDateFormat, CultureInfo.InvariantCulture);
cmd.Parameters.AddWithValue("#to", to);
cmd.Parameters.AddWithValue("#from", from);
try this
cmd.Parameters.AddWithValue("#to",Convert.ToDateTime(date_to.Text));
cmd.Parameters.AddWithValue("#from",Convert.ToDateTime( date_from.Text});
I think your date format may caused the issue. You must use date format supported by the SQL provider. Most SQL uses MM-dd-yyyy format. So if you pass 21-1-2014, SQL server don't accept it because 21st month don't exist.
If the problem persists while executing your code, perhaps it is due to two important reasons:
You have used the DateTime.Now.ToShortString or similar auto conversion method, and
You changed the computers default Datetime format in the setting.
Change the Datetime format of the computer or change the autoconversion to 'parse' method.

Problems by inserting values from textboxes

I'm trying to insert the current date to the database and i allways get the message(when i press the button on the form to save to my access database), that the data type is incorect in the conditional expression.
the code:
string conString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=C:\\Users\\Simon\\Desktop\\save.mdb";
OleDbConnection empConnection = new OleDbConnection(conString);
string insertStatement = "INSERT INTO obroki_save "
+ "([ID_uporabnika],[ID_zivila],[skupaj_kalorij]) "
+ "VALUES (#ID_uporabnika,#ID_zivila,#skupaj_kalorij)";
OleDbCommand insertCommand = new OleDbCommand(insertStatement, empConnection);
insertCommand.Parameters.Add("#ID_uporabnika", OleDbType.Char).Value = users.iDTextBox.Text;
insertCommand.Parameters.Add("#ID_zivila", OleDbType.Char).Value = iDTextBox.Text;
insertCommand.Parameters.Add("#skupaj_kalorij", OleDbType.Char).Value = textBox1.Text;
empConnection.Open();
try
{
int count = insertCommand.ExecuteNonQuery();
}
catch (OleDbException ex)
{
MessageBox.Show(ex.Message);
}
finally
{
empConnection.Close();
textBox1.Clear();
textBox2.Clear();
textBox3.Clear();
textBox4.Clear();
textBox5.Clear();
}
I have now cut out the date,( i made access paste the date ), still there is the same problem. Is the first line ok? users.idtextbox.text?
Please help !
try Changing
insertCommand.Parameters.Add("#datum", OleDbType.Char).Value = DateTime.Now;
to
`insertCommand.Parameters.Add("#datum", OleDbType.Char).Value
= DateTime.Now.ToString("dd MMM yyyy HH:mm");`
( or some other acceptable date format)
Assuming that your database actually holds dates, and not strings, for the date column - I think you're trying to insert char values into your date column.
Change
insertCommand.Parameters.Add("#datum", OleDbType.Char).Value = DateTime.Now;
to
insertCommand.Parameters.Add("#datum", OleDbType.Date).Value = DateTime.Now;
I think you are getting issue due to the date format set in your regional settings and the date format accepted by MS Access.
You can use a specific date format as mentioned in following code.
DateTimeFormatInfo ukDTFomat = new CultureInfo("en-GB", false).DateTimeFormat;
DateTime.Now.ToString("yyyy-MM-dd", ukDTFomat);
You can simplify your OleDb usage by adding parameters like this:
OleDbParameter param = new OleDbParameter("#datum", DateTime.Now);
command.Parameters.Add(param);
This uses the override of the OleDbParameter that takes a string (the parameter name) and an object (whatever the value should be for the parameter). This lets OleDb figure out the correct parameter type for you (and saves you a lot of work typing and changing parameter types).
Update: just noticed this is Jet. All bets are off when it comes to Access, so I'm by no means sure the above will work.
You should use the type OleDbType.Date in the parameter. That maps to a DateTime value in .NET and an OLE date (internally represented as double) in the database. That's what Access uses for storing dates.
With any of the other date formats in OleDbType, it will be converted to a string representation that Access doesn't recognise as a date.
If you use OleDbType.Char the DateTime value will be converted to a string using the current culture in .NET, which may or may not be understood by Access depending on what the culture happens to be. In your case it seems that it was not understood.
Are you sure the problem is the date value? I.e., are the other columns really of type Char? For date values, you should use OleDbType.DBDate but you should also use the appropriate type for the other columns.
EDIT
Tested against an Access database with a date column, the following worked (although stripped the time obviously):
cmd.Parameters.Add( "#DateColumn", OleDbType.DBDate ).Value = DateTime.Now;
As well as (which included the time)
cmd.Parameters.Add( "#TestDate", OleDbType.Date ).Value = DateTime.Now;
EDIT As with the date parameters, you should be passing specific types for the other values:
insertCommand.Parameters.Add("#ID_uporabnika", OleDbType.Integer).Value = int.Parse( users.iDTextBox.Text );
insertCommand.Parameters.Add("#ID_zivila", OleDbType.Integer.Value = int.Parse( iDTextBox.Text );
insertCommand.Parameters.Add("#skupaj_kalorij", OleDbType.Integer).Value = int.Parse( textBox1.Text );

Categories