I am currently developing a C# MySQL Export Utility. Due to this I am not going to know the fields or the data types of each field in the table.
When I export the data from the table in the database it displays a MySQLConversionException stating that it is unable to Covert MySQL Date/Time to System.DateTime. It was doing this when I ran the code:
if (!reader.isDBNull(fieldCount)){}
However, when the exception was thrown on this line I fixed it by adding Allow Zero DateTime=true to the MySQL Connection string but not it is displaying the error when I run the code
string value = reader.getString(field);
How can I get around this issue bearing in mind I am not going to know what data type is or what the value is going to be.
Thanks for any help you can provide.
You can get the raw value as object:
object value = reader[field];
Then decide what to do based on its type:
if (value is string)
{
string sVal = value.ToString();
//handle as string...
}
else if (value is DateTime)
{
DateTime dtVal = (DateTime)value;
//handle as DateTime...
}
else
{
//some other type
}
Maybe not elegant, but should work.
If you read DATETIME values with MySQL Connector/Net and set 'Allow Zero Datetime', then you should use the reader.GetValue() method; in this case the reader will return a MySqlDateTime object with '0000-00-00 00:00:00' value.
Connector/Net Connection String Options Reference
Note, than .NET DateTime.MinValue = 00:00:00.0000000, January 1, 0001.
Also, try dotConnect for MySQL components.
I tackled a problem similar to this in an old open source project of mine. See it here in my Util.DefaultConvert() method.
The trick is to use Type.GetTypeCode() and switch on the result.
Then implement a strict conversion for each type. There is most likely other code in there you can check out to do what you need. I have a MySql provider in there as well.
Related
I use the layer2 cloud connector synchronisation tool to synchronize between a sql database and a sharepoint database on the right side. When synching from right to left (from SP to SQL) in a datetime field "dl date" there can be empty values. I established a dynamic column in the tool, which should return "01.01.1753" if in SP "dl date" was empty or just the regular date if it was not empty. That's due to our SQL database, which doesn't accept empty values but has to have this weird "01.01.1753" as empty value.
In the definition of the dynamic field I use the following C#-Code:
if(String.IsNullOrEmpty(NächstesFSKontrolldatum.ToString())) {
return DateTime.Parse("01.01.1753"); } else { return
NächstesFSKontrolldatum; }
But no matter how I compare the field "NächstesFSKontrolldatum" (aka "dl date") if it's null, it doesn't fire the part of the condition for beeing null.
When the tool finally writes just the date to sql there is an error which says can't put string '' into date field. I guess that always my second case of the condition fires and he tries to write just empty values into the database.
Because this code runs inside of the layer2 tool, I don't know how to debug or write to the console. Maybe you know or it's not possible?
Do you know, which comparison I have to make?
Andreas
I think is beter test if the 'NächstesFSKontrolldatum' can be parsed with a TryParse
DateTime testDate;
if(!DateTime.TryParse(NächstesFSKontrolldatum.ToString(), out testDate))
{
return DateTime.Parse("01.01.1753");
}
else
{
return testDate;
}
This way you're sure the value returned can be readed as a Date
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.
I have an app which worked fine with Sql Server. I have a DevExpress grid which shows just a record in carousel mode (not that this matters, I hope).
Now, I have changed the code to be database-agnostic and I'm testing MySql. When the user modified the record and accepted the changes, I was getting the following error:
Concurrency violation: the UpdateCommand affected 0 of the expected 1
records
After some research, I've come to the conclussion that the problem lies in DATETIME fields. I am using "Allow Zero Datetime=False; Convert Zero Datetime=True;" in my MySql connection string so I can convert default DATETIME values to .Net DateTime objects. The autogenerated UpdateCommand includes every field in the where clause, and I guess the comparison fails when the MySql DATETIMEs are set to the default value, as removing DATETIME fields the problem went away.
I have a Primary Key column, and the user isn't allowed to modify it, so what's the right way to issue a custom UpdateCommand so that there's only one field in the WHERE clause?
My current code for accepting changes:
Dim builder As DbCommandBuilder = m_Conn.CreateCommandBuilder(m_Adapter)
m_Adapter.Update(m_DataTable)
CreateCommandBuilder is an extension method on IDbConnection to create the correct an object with a correct implementatin of the DbCommandBuilder interface.
Your DBCommandBuilder should have a ConflictOption Property that needs to be set.
Presumably you want to set it to ConflictOption.OverwriteChanges.
I'm not sure if it works when you initialize the Adapter commands via the CommandBuilder Constructor but a
var builder = new MySqlCommandBuilder();
builder.ConflictOption = ConflictOption.OverwriteChanges;
builder.DataAdapter = m_Adapter;
should do.
Instead of using "Allow Zero Datetime=False; Convert Zero Datetime=True;" in your connection string (which FYI I'm not familiar with), I'd recommend using DateTime.Parse(value). You'll probably want to write a function so that you can easily handle nulls as well.
private DateTime getDateTimeField(string dbValue)
{
if (dbValue == null)
{
return new DateTime();
}
else {
return DateTime.Parse(dbValue);
}
}
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;-- ...
I have a C# application over MySql, using MySQL Connector; I'm trying to make a
DataReader request, the query executes fine, however, when trying to access a DateTime field, i'm getting MySqlConversionException {"Unable to convert MySQL date/time value to System.DateTime"}
this is the prototype
if (dr != null && !dr.Read()) return;
sesion.Id = Convert.ToInt32(dr["id"]);
sesion.Usuario = Convert.ToInt32(dr["usuario"]);
sesion.Estado = Convert.ToByte(dr["estado"]);
// doesn't work
sesion.FchCreacion = Convert.ToDateTime(dr["fch_creacion"]);
Any suggestions?
Thanks in advance
This error sometimes occurs if you have zero datetime values in your MySQL database (00/00/0000 00:00). Try adding this to the end of your connection string:
Allow Zero Datetime=true
There are a few potential gotchas when converting between MySQL dates/times and .NET DateTimes, but there's a useful section in the MySQL documentation with advice on how to handle the issues.
I'd suggest it may be a culture specific error - is the applicaiton on the same server as the DB, and do they have the same culture settings?
Also, is the column definitely a datetime in MySQL?
It could also be a DBNull value.