C# timestamp zero value can't read in my reader - c#

I'm having problem in getting the updated timestamp value which is returning 0000-00-00 00:00:00. My reader cannot read the data it gives an error saying Invalid DateTime.
I want to get only the time under TimeIn and TimeOut fields.
This is my code:
try
{
SQLConn.sqL = "SELECT * FROM tblinformation WHERE " + search + " LIKE '" + strSearch + "%'";
SQLConn.ConnDB();
SQLConn.cmd = new MySqlCommand(SQLConn.sqL, SQLConn.conn);
SQLConn.dr = SQLConn.cmd.ExecuteReader();
ListViewItem x = null;
listView2.Items.Clear();
while (SQLConn.dr.Read() == true)
{
x = new ListViewItem(SQLConn.dr["AttendanceNo"].ToString());
x.SubItems.Add(SQLConn.dr["RFIDNo"].ToString());
x.SubItems.Add(SQLConn.dr["IDNumber"].ToString());
x.SubItems.Add(SQLConn.dr["FullName"].ToString());
x.SubItems.Add(SQLConn.dr["Designation"].ToString());
x.SubItems.Add(DateTime.Parse(SQLConn.dr["TimeIn"].ToString()).ToShortTimeString());
x.SubItems.Add(DateTime.Parse(SQLConn.dr["TimeOut"].ToString()).ToShortTimeString());
x.SubItems.Add(SQLConn.dr["VPlateNo"].ToString());
listView2.Items.Add(x);
}
}
catch (Exception ex)
{
Interaction.MsgBox(ex.ToString());
}
finally
{
SQLConn.cmd.Dispose();
SQLConn.conn.Close();
}

The MySql provider for ADO.Net retrieves MySql Timestamp columns as .Net DateTime objects. You do not want to call SQLConn.dr["TimeIn"].ToString(), especially when you're just gonna try to Parse() it again. The object in the reader field is already a DateTime value, so you can just do this:
x.SubItems.Add( ((DateTime)SQLConn.dr["TimeIn"]).ToShortTimeString() );
That will perform way better and be much less prone to errors. I'm not 100% certain it will fix the issue in the question, but it will certainly make debugging easier, especially if you separate it to two lines like this:
DateTime temp = (DateTime)SQLConn.dr["TimeIn"];
x.SubItems.Add( temp.ToShortTimeString() );
Now you can put a break point on the first line and check the actual value in the debugger.
While I'm here, I can't say strongly enough how BAD this is:
SQLConn.sqL = "SELECT * FROM tblinformation WHERE " + search + " LIKE '" + strSearch + "%'";
This is the kind of code where you find out one morning you were hacked six months ago.
Don't do it.
You need query parameters, like this:
SQLConn.cmd = new MySqlCommand("SELECT * FROM tblinformation WHERE column LIKE #search + '%';", SQLConn.conn);
SQLConn.Parameters.Add("#search", MySqlDbType.VarChar, 50).Value = strSearch;
Even internal-only apps need to work this way. As a bonus, it also tends to perform faster, and can help with many DateTime and numeric formatting issues, since you work with native .Net types for the parameter values.

MySQL Server allows an "invalid" DATETIME value 0000-00-00 00:00:00 to be stored (as long as the NO_ZERO_DATE server mode isn't set).
Since this isn't a valid .NET DateTime value, you need to add AllowZeroDateTime=true to your connection string, which will cause Connector/NET to return all DATETIME columns as the special MySqlDateTime type.
Alternatively, if you still want to use .NET's DateTime struct instead of MySqlDateTime, you can specify ConvertZeroDateTime=true in your connection string, which will convert 0000-00-00 00:00:00 to DateTime.MinValue when retrieving it from the database.
However, you should carefully check all your database insertion code to make sure you're not inserting invalid date/time values that MySQL Server is silently converting to 0000-00-00. You should also use STRICT mode if at all possible, to avoid silent data loss.

Related

I want to set the date, but I couldn't, how can I do it? [duplicate]

This question already has answers here:
get date without time in c#
(5 answers)
Closed 1 year ago.
I don't want to get the last minutes and seconds of the date option. How can I do this?
My code:
string storeShort = "IDEA" + orderItem.id + 'T' + DateTime.Parse(orderItem.createdAt, System.Globalization.CultureInfo.CurrentCulture);
It comes like this: IDEA8T30.03.2021 14:55:11
I want like this: IDEA8T30.03.2021
I don't want to get the last part here ie hours minutes and seconds.How can I modify my code here accordingly?
The trick can be done using ToString. The code should look like this:
var someDateTime = DateTime
.Parse(orderItem.createdAt, System.Globalization.CultureInfo.CurrentCulture)
.ToString("dd.MM.yyyy");
string storeShort = "IDEA" + orderItem.id + 'T' + someDateTime;
// OR nicer:
var storeShort = $"IDEA{orderItem.id}T{someDateTime}";
The possible formatting options can be found here.
You could try simply adding ".Date" at the end of the parse to ignore the "time" part, like this :
string storeShort = "IDEA" + orderItem.id + 'T' +
DateTime.Parse(orderItem.createdAt,
System.Globalization.CultureInfo.CurrentCulture).Date;
Important:
You can never know how the data will look like on different systems, because of the potential different culters on different systems.

SqlCommand with parameters accepting different data formats

Imagine this code:
string value = "1.23";
string query = "UPDATE MYTABLE SET COL1=#p1";
SqlCommand cmd = new SqlCommand(query, connection);
cmd.Parameters.AddWithValue("#p1", value);
cmd.ExecuteNonQuery();
On my database it will work with value="1.23" if COL1 is decimal type column. But it will fail if value is "1,23" (comma instead of a dot as a decimal point). The error is
Error converting data type nvarchar to numeric
I'd like it to work in both cases with "value" being a string variable.
Unfortunately I cannot just replace comma for the dot as this code is going to be more universal, dealing both with numeric and varchar columns
Is there any way that an query accepts a parameter with number written as a string both with dot and a comma and correctly puts it in into table?
Thanks for any help
If the value isn't semantically a string, you shouldn't send it as a string. The type of the parameter value is important, and influences how it is transmitted and can lead to culture issues (comma vs dot, etc).
If the value is semantically a decimal, then use something like:
string value = "1.23";
var typedValue = decimal.Parse(value); // possible specifying a culture-info
//...
cmd.Parameters.AddWithValue("#p1", typedValue);
Then it should work reliably.
Unrelated, but you can make ADO.NET a lot easier with tools like "Dapper":
connection.Execute("UPDATE MYTABLE SET COL1=#typedValue", new { typedValue });

Input string was not in a correct format. C# error SQL database

I have a very BIG PROBLEM.
I want to delete a row from my database sql in C#.
here is my code:
int x = Convert.ToInt32(dataGridView1.SelectedCells[0].Value);
cmd.Parameters.Clear();
cmd.CommandText = "delete from Table2 where Name=#N";
cmd.Parameters.AddWithValue("#N", x);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
and finally im get a problem
Input string was not in a correct format.
Help me.
I get the error in first Line.
First problem:
dataGridView1.SelectedCells[0].Value is not a valid integer value, so Convert.ToInt32 fails.
Did you mean
string x = dataGridView1.SelectedCells[0].Value;
instead?
Second problem:
You are comparing the Name field to an integer value. I'm assuming Name is a _string_ value in the database (otherwise it's poorly named). When SQL looks for matching values, it will try to convert every value ofNamein the database to a number. if ANY value in theName` field is not a valid number, the query will fail.
I've read that null or empty string will return 0 (to be confirmed)
Here my guess :
Depending of your country, numbers should be wrote :
1.234
or
1,234
Solution
Hugly solution : You can simply do a :
Convert.ToInt32(dataGridView1.SelectedCells[0].Value.Replace(".",","));
Good solution : Or use Convert.ToInt32(String, IFormatProvider) :
Convert.ToInt32(dataGridView1.SelectedCells[0].Value,CultureInfo.CurrentCulture)
EDIT -1 without comment, i'm please to help.

How can I resolve this error an c#

I want to insert data into a database table:
myCommand.CommandText = "INSERT INTO Selectionner (IdPrestation,
IdPhrase, DegreUrgence,RisqueConcerne,rowguid,Cotation) " +
"VALUES ('" +new Guid(emp.IdPrestation) +
"', '" +new Guid(emp.IdPhrase)+ "', '" +
emp.DegreUrgence + "','" + emp.RisqueConcerne + "','" +
new Guid(emp.rowguid) + "','" + emp.Cotation + "')";
But this returns an error:
Guid should contain 32 digits with 4 dashes
(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
How can I resolve this error ?
One or many of your
emp.IdPrestation //Or
emp.IdPhrase //Or
emp.rowguid //Check them before creating
is/are not a GUID. That is why it is throwing an error.
EDIT: starts
How to use Guid.TryParse() which returns true if the parse operation was successful; otherwise, false.
//How to parse safely
Guid IdPrestation;
Guid IdPhrase;
Guid rowguid;
if(Guid.TryParse(emp.IdPrestation, out IdPrestation) &&
Guid.TryParse(emp.IdPhrase, out IdPhrase) &&
Guid.TryParse(emp.rowguid, out rowguid) )
{
//all variables have been parse successfully
//Execute the sql query as follows using parameters
}
EDIT: ends
Also, passing parameters as direct string with inline sql is an unsafe bad practice. Instead use a parameterised query.
myCommand.CommandText = "INSERT INTO yourTableName (c1, c2, ...)
VALUES (#p1, #p2,...)";
myCommand.Parameters.Add(new SqlParameter("p1", valueforCol1));
myCommand.Parameters.Add(new SqlParameter("p2", valueforCol2));
...
Try to use a parameterised query as a first improvement.
Then, try to use Guid.Parse(string s) instead of new Guid(string s). That way, i expect that an exception will be raised for the strings that are not compliant.
The constructor might be a little to permissive, and in this case you would want to fail-fast so that you know what field is giving you trouble.
You cannot create GUID simply from a string ,the string needs to be guid compliant
Guid originalGuid = Guid.NewGuid();
originalGuid.ToString("B") gets converted to {81a130d2-502f-4cf1-a376-63edeb000e9f}
Similarly
"N" - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (32 digits)
"D" - xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (32 digits separated by hyphens)
"B" - {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} (same as "D" with addition of braces)
"P" - (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) (same as "D" with addition of parentheses)
"X" - {0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00.0x00}}
The guid itself has no format. It is just a value. Note, that you can create guids using NewGuid or using the guid's constructor. Using NewGuid, you have no control over the value of the guid. Using the guid's constructor, you can control the value. Using the constructor is useful if you already have a string representation of a guid (maybe you read it from a database) or if you want to make it easier to interpret a guid during development. You can also use the Parse, ParseExact, TryParse, and TryParseExact methods.
So, you can create guids like this:
Guid g1 = Guid.NewGuid(); //Get a Guid without any control over the contents
Guid g2 = new Guid(new string('A',32)); //Get a Guid where all digits == 'A'
Guid g3 = Guid.Parse(g1.ToString());
Guid g4 = Guid.ParseExact(g1.ToString("D"),"D");
Guid g5;
bool b1 = Guid.TryParse(g1.ToString(), out g5);
Guid g6;
bool b2 = Guid.TryParseExact(g1.ToString("D"),"D", out g6);

C# times matching

I have written a small function in C# which isn't my main launguage so is coming across a little foreign to me.
public bool CheckForKey(string key)
{
string strKeyTime = Decode(key);
//valid key will be current time +- 5 minutes
string strTheTime = DateTime.Now.ToString("HH:mm:ss tt");
if (strKeyTime == strTheTime)
{
return true;
}
else
{
return false;
}
}
I need to alter this to allow for 5 minutes, so
if (strKeyTime == strTheTime)
needs to be
if (strKeyTime == strTheTime + or - 5 minutes)
my problem is matching the times as they are strings, perhaps convert key(original time) back to a date first and then do it, but I am pretty new to c#
If you convert (or keep) them both to DateTimes you can use TimeSpan:
TimeSpan delta = dateTime1 - dateTime2;
if (Math.Abs(delta.TotalMinutes) <= 5) { ... }
Look into using the DateTime.ParseExact (or any of the Parse... methods) to parse your strKeyTime, and then do something similar to the above.
To convert your sent string to the equivalent DateTime value, use the following code:
var keyDateTime = Convert.ToDateTime(strKeyTime);
var strTheTime = DateTime.Now
from here, you can use this value to compare with your original time value as the following:
if (keyDateTime == strTheTime || (keyDateTime > strTheTime && keyDateTime < strTheTime.AddMinutes(5))
{
return true;
}
the previous block of code will first check if we got an exact match, or the time sent to the method is between the original time and a time shift of additional 5 minutes.
that's it, if this is not what you need, let me know so I may update my answer for you, thanks.
-- if my answer is correct, don't forget to "Mark as answer".
"perhaps convert key(original time) back to a date first and then do it" sounds like a sound solution. I'd do it this way:
Convert both strings to DateTime instances.
Store difference in TimeSpan instance using DateTime.Subtract(DateTime value) ( http://msdn.microsoft.com/en-us/library/8ysw4sby.aspx )
Check if TimeSpanInstance.TotalMinutes is less than or equal to 5.
The first step is something I can't really give you any advice on without information concerning how your string is formatted. However, once this is done, the rest should be easy.

Categories