Error when updating date field in sql server using c# - c#

I am trying to insert a date (date only, not datetime) into sql table (the datatype is date).
I am using the '23/07/2013' format which I am getting from jquery datepicker.
When I execute the following sql, I am getting following error.
SQL: UPDATE qmsAuditFindings SET FindDate='23/07/2013' WHERE AuditID=37
Please advise.
Also its worth mentioning that the insert statement with the exact format works just fine. Just the update that does not.

At the surface, this is simply a formatting issue - but "fixing the formatting" is the wrong way to address this; you should parameterize, such that formatting simply does not apply. Dates don't have a "format", as such - they are just numbers. For example, what we should probably execute is:
UPDATE qmsAuditFindings SET FindDate=#findDate WHERE AuditID=#auditId
To do that you get the DateTime value in your .NET code, and do something like:
DateTime findDate = ...
int auditId = ...
using(var cmd = connection.CreateCommand()) {
cmd.CommandText =
"UPDATE qmsAuditFindings SET FindDate=#findDate WHERE AuditID=#auditId";
cmd.Parameters.AddWithValue("findDate", findDate);
cmd.Parameters.AddWithValue("auditId", auditId);
cmd.ExecuteNonQuery();
}
or more simply with a tool like "dapper":
DateTime findDate = ...
int auditId = ...
connection.Execute(
"UPDATE qmsAuditFindings SET FindDate=#findDate WHERE AuditID=#auditId",
new { findDate, auditId });

Related

Troubleshooting "Data type mismatch in criteria expression." during MS Access Insert.Into

I'm creating a basic customer inventory application, and when converting the code from using SQL Server to using MS Access (which I'm quite a bit less versed in), I ran into a "Data type mismatch" error when trying to do a basic insert.
I've looked into several similar questions here, and double checked the msdn syntax guide, but I can't find a reason why the script I've written would generate that error. I changed my code several times to try and ensure proper data type (ending up with what I have below with explicit typing and adding the value later). I've actually even taken the string and pasted it into MS Access (sans white space and double quotes), and it seems to work just fine with the values given. At this point, I'm really and truly stumped, and I'm wondering if it might just be a quirk with the Oledb adapter? Any help would be appreciated. Thanks.
// SQL query defined elsewhere:
public static readonly string sqlAddCustomerNotes = "INSERT INTO CustomerNotes (Customer_ID, Notes, NotesDate) "
+ "VALUES(#Customer_ID, #Notes, #NotesDate);";
// end sql query
// data access function
public static void addNotes(int customerID, string notes, DateTime notesDate)
{
string query = Scripts.sqlAddCustomerNotes;
using (
OleDbCommand dbCommand = new OleDbCommand()
{
Connection = new OleDbConnection(ConnectionAccess.connString),
CommandType = CommandType.Text,
CommandText = query,
Parameters =
{
new OleDbParameter("#Customer_ID", OleDbType.Integer),
new OleDbParameter("#Notes", OleDbType.LongVarChar),
new OleDbParameter("#NotesDate", OleDbType.DBTimeStamp)
}
}) // end using parenthetical
{ // begin using scope
dbCommand.Parameters[0].Value = customerID;
dbCommand.Parameters[1].Value = notes;
dbCommand.Parameters[2].Value = notesDate;
foreach (OleDbParameter param in dbCommand.Parameters)
{ // replace ambiguous null values with explicit DBNulls.
if (param.Value == null)
{
param.Value = DBNull.Value;
}
}
dbCommand.Connection.Open();
int rowsAffected = dbCommand.ExecuteNonQuery();
dbCommand.Connection.Close();
Console.WriteLine($"Rows affected: {rowsAffected}");
}
} // end addCustomerNotes
/*
table "CustomerNotes" has the following columns:datatypes
CustomerNotes_ID: AutoNumber
Customer_ID: Number
Notes: Memo
NotesDate: Date/Time
CreateDate: Date/Time
test case (in code) was:
#Customer_ID = 5
#Notes = "customer might change last name to simpson."
#NotesDate = {6/26/2019 12:05:39 PM}
*/
It probably is a date, not a timestamp:
new OleDbParameter("#NotesDate", OleDbType.DBDate)
Considering June7's comment about delimiters, it seems the issue lies in some issue inherent to the OleDbParameter type. In SQL Server terms, I do want DateTime (not Date), but representing it as a DBTimeStamp seems to make it unrecognizable by Access.
For the time being, I've sent the date as a VarChar and allowed Access to convert it however its internal engine sees fit. It feels/seems wrong, but it does, in fact, solve the problem.
Parameters =
{
new OleDbParameter("#Customer_ID", OleDbType.Integer),
new OleDbParameter("#Notes", OleDbType.LongVarChar),
new OleDbParameter("#NotesDate", OleDbType.VarChar)
}
EDIT: Just saw June7's latest comment, and there was in fact, an answer in another thread. OleDbType.DBDate doesn't do what I want, but OleDbType.Date does.

Query from C# code outputting differently from SQL Server query

Working with:
ASP.Net web-forms application
C# code not vb.net
SQL Server with hard coded test data
Note: this issue doesn't cause any errors or cause any disruption in the code, however it outputs differently from expected.
What I am trying to do is populate a Gridview using code behind file, which can be updated by the user on button click.
Code to populate:
protected void PopulateReport()
{
// create connection and add commands
SqlConnection con = new SqlConnection(GetConnectionString());
con.Open();
if(RP_SelectEmp.Text == "ALL")
{
string query1 = "SELECT RequestID, empName, RequestType, RequestDesc, RequestStartDate FROM TOR WHERE (RequestStartDate > #StartDate)" +
" AND (RequestEndDate < #EndDate) AND (granted = #State)";
SqlCommand cmd = new SqlCommand(query1, con);
// needed conversions
DateTime startD = Convert.ToDateTime(RP_FromDateSelect.Text);
DateTime endD = Convert.ToDateTime(RP_EndDateSelect.Text);
Boolean state = Convert.ToBoolean("True");
// needed parameters
cmd.Parameters.AddWithValue("#State", state);
cmd.Parameters.AddWithValue("#StartDate", startD);
cmd.Parameters.AddWithValue("#EndDate", endD);
// import into gridview
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
GridView1.DataSource = reader;
GridView1.DataBind();
}
else
{
RP_ErroField.Text = "failed to bind data (reader not read) check C# code";
}
}
con.Close();
}
}
This compiles and returns no errors but outputs:
The database table includes all the correct data types and column names:
What I have tried:
creating a static data Source and passing in the same select string from the above code (this returns the hard coded event, with the same exact input from the fields seen in the picture) - which tells me the query isn't wrong AddingDataSource,InputingData,Correct event Grabbed
I have tried changing the conversions in the code, DateTime.Parse and Convert.ToDateTime had the same result. Same can be said for bool and Boolean
I have tried the each where clause separately and got the same no data to display result.
I have debugged this if statement for 2 hrs and all the variable data is doing exactly what it should (going to the if, converting, setting the values, running the reader, and databinding)
I don't know what else to try. I would like help on an action plan to fix this; maybe I am missing something, or my approach is wrong/outdated.
This is really just a debugging exercise.
First, double-check that you haven't simply named the two date-picker controls backwards! That happens a lot.
Next: go to SSMS, and take your existing query:
SELECT RequestID, empName, RequestType, RequestDesc, RequestStartDate
FROM TOR
WHERE (RequestStartDate > #StartDate)
AND (RequestEndDate < #EndDate) AND (granted = #State)
Now; we know that you've used Convert.ToDateTime to parse the dates, and that's great. You might want to check the cultures that it is parsing to what you expect it to parse to (is 1/2/2018 the first of Feb? or the 2nd of Jan?), and when you're 100% sure what the actual date of startD and endD are, prepend these to your query using an unambiguous format (just to help us debug); do the same thing with state; for example:
DECLARE #StartDate datetime = '01 Jan 2018';
DECLARE #EndDate datetime = '03 Jan 2018';
DECLARE #State bit = 1;
or are they?
DECLARE #StartDate datetime = '01 Jan 2018';
DECLARE #EndDate datetime = '01 March 2018';
DECLARE #State bit = 1;
So now we have spoofed the parameters and you have the exact same query: run it. 99% of the time, doing this will show you what is wrong with the query. I would expect that the query in SSMS now behaves like the query from your application does. So; now go fix it!

datetime in C# vs, SQL and GETDATE() from SQL Server

I use GETDATE() in a SQL Server stored procedure to insert a date into the SQL Server database table.
After that I need to implement a C# function which is based on datetime input parameter finds if the date was saved in the tables.
The datetime in C# and SQL are different. How do I convert from C# datetime to SQL datetime which has a form of yyyy-mm-ddT:yy:mm:ss.mmm? I need to specify explicitly yyyy-mm-ddT:yy:mm:ss.mmm.
Will be happy for all propositions/possible ways.
DateTime in .Net framework and SQL Server (if it is DateTime type field) is irrespective of the format. Format is only useful for displaying output.
If your field in SQL Server is of DateTime type then you can query it from C# code using parameterized query something like:
public DataTable GetRecords(DateTime dtParameter)
{
DataTable dt = null;
using (SqlConnection conn = new SqlConnection("connection string"))
{
using (SqlCommand cmd = new SqlCommand("SELECT * from yourTable where DateField = #dateparameter"))
{
conn.Open();
cmd.Parameters.AddWithValue("#dateparameter",dtParameter);
SqlDataReader dr = cmd.ExecuteReader();
//...rest of the code
dt.Load(dr);
}
}
return dt;
}
Datetimes between C# and SQL are 100% compatible. The format shouldn't make any difference if you are passing them as DateTimes. If you are generating a SQL string then I would highly recommend changing to SQL Parameters so you don;t have to worry about any formatting issues.
A datetime has no format at all, it has a value. SQL-DateTimes and C# DateTimes are compatible. So don't convert it (to string) at all but pass it as datetime-parameter to the database.
Then you're safe if the DateTime value is within SqlDateTime.MinValue(January 1, 1753) and SqlDateTime.MaxValue(December 31, 9999).
You should never write DateTime.Now from client code to insert into the database as this will be based on the clients local time; do this
public DateTime GetDatabaseTime()
{
var parameter = new SqlParameter("time", SqlDbType.DateTime2)
{
Direction = ParameterDirection.Output
};
using (var connection = new SqlConnection(ConnectionString))
{
connection.Open();
using (var command = new SqlConnection("SELECT #time = SYSDATETIME()", connection))
{
command.ExecuteNonQuery();
}
}
return (DateTime)parameter.Value;
}
Also you should never use DATETIME in SQL Server you should always use DATETIME2 as DATETIME is less accurate than C#::DateTime and it will lead to rounding errors. I know this from bitter experience.
If you are using Entity Framework, and your database is using datetime and not datetime2, the trick is to use SqlDateTime to match the fact that .Net goes to nanosecond, versus sql's millisecond precision. You can use your DateTime variable in .net.. for a SqlDateTime instance, and then you can uniquely identify a record down to the millisecond.
System.Data.SqlTypes.SqlDateTime entry2 = new System.Data.SqlTypes.SqlDateTime(new DateTime(dto.LookUpDateTime));
DateTime entry = entry2.Value;
var existticket = from db in context.Tickets
where db.LookupDateTime == entry && db.UserId == UserId
select db;

SQLite command to insert current datetime not working through c#

I am trying to insert current date in my table from a c# application, i am doing this the following way:
sqlite_cmd.CommandText = "INSERT INTO tablename (column1,creation_date) VALUES ('abcd_" + (id) + "',CURRENT_TIMESTAMP);";
sqlite_cmd.ExecuteNonQuery();
But this throws error saying that CURRENT_TIMESTAMP is not a valid field.
I double checked the above query using sqlite manager plugin for firefox and it seems to work correctly.
P.S. - id in the above query is an int variable that is set by c# application.
CURRENT_TIMESTAMP is only valid in column definition.
As a expression, you can use DATETIME('NOW'). Try:
sqlite_cmd.CommandText = "INSERT INTO tablename (column1,creation_date) VALUES ('abcd_" + (id) + "', DATETIME('NOW'));";
Try using this:
using(SQLiteCommand cmd = new SQLiteCommand(yourSqliteConnection))
{
cmd.CommandText = "INSERT INTO tablename (column1,creation_date) VALUES (?,?)";
cmd.Command.Parameters.AddWithValue("#p1",string.Format("abcd_{0}",id));
cmd.Command.Parameters.AddWithValue("#p2",DateTime.Now.ToString("s"));
cmd.CommandType= CommmandType.Text;
cmd.ExecuteNonQuery();
}
DateTime.Now.ToString("s") means convert this datetime into XSD format.
SQLite does not have a DateTime Format in its own. so everything you need is to convert it into a fixed format of TEXT and then insert and serach according to this format.
XSD is a fixed format for DateTime. it does not change if format of DateTime Change.
Remember when you need to do a search (SELECT) command based on DateTime try to convert it as shown above before doing any operation in SQLite.

inserting datetimepicker value to SQL Server 2008

I'm trying to insert a value from a datetimepicker value to a SQL Server table.
My table looks like this
Profile (Id, Name,..., DateofBirth(date)...)
I have tried this to convert datetime picker value to
string dt = dateTimePicker.Value.ToString("yyyy-mm-dd hh:MM:ss");
Insert into profile (id, DateofBirth)
values(id, CONVERT(datetime, CONVERT( varchar(11), dt, 101));
also use this
var date = new DateTime(dateTimePickerText);
also use this
DateTime date = DateBox.Value.Date;
string sDate = date.ToString("dd-MM-yy", System.Globalization.CultureInfo.InvariantCulture);
DateTime dateInsert = Convert.ToDateTime(sDate);
but can't able to insert the date into the database. 2nd how can I retrieve back the date from database?
You must have to use SqlParameter.
sql="Insert into profile (id, DateofBirth) values (#id,#DateofBirth)";
using(SqlCommand cmd=new SqlCommand(sql,conn))
{
cmd.Parameters.Add("#id",SqlDbType.Int).Value=10;
cmd.Parameters.Add("#DateofBirth",SqlDbType.DateTime).Value=dateTimePicker.Value;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
Personally I'd get into the habit of using parameters for all of your SQL queries. That way you avoid SQL injection attack vector and you can also specify the parameter type as datetime. See this answer for example.

Categories