I have a C# program and I want to run a MySQL query that insert a record. In this record I have a timestamp field that MUST BE the server timestamp, not the client timestamp.
So, I write this:
start_session = new MySqlDataAdapter("INSERT INTO CUBE_WORKTIME(ID_WORKTIME,
ID_RISORSA_FK,DATA,ORA_INIZIO_EVENTO, ORA_FINE_EVENTO,
ID_CDC_FK, CAUSALE, LAST_EVENT)
VALUES ('', '"+ idrisorsa_global + "', DATE(NOW()),NOW(),
NULL, '"+ IDCDC +"', 'Login', 'Y')", connection);
DataTable start_session_dataset = new DataTable();
start_session.Fill(start_session_dataset);
This query works well, the ID_RISORSA_FK and IDCDC fields are correct. But the date and the datetime are 0000-00-00 and 0000-00-00 00:00:00.
I also tried adding the quotes, but no effects.
Any ideas?
The first thing to change is the use of an MySqlDataAdapter to just insert a record. While this could work it is not the correct class to use for this work. A simple MySqlCommand is the correct object to use and with a lot less of infrastructure required
The second thing to change is the way in which you build your sql query. Do not concatenate together strings to form an sql command but use Parameters. This avoid Sql Injection and parsing problems.
So your code could be rewritten as
string cmdText = #"INSERT INTO CUBE_WORKTIME
(ID_RISORSA_FK,DATA,ORA_INIZIO_EVENTO, ORA_FINE_EVENTO,ID_CDC_FK,
CAUSALE, LAST_EVENT) VALUES (#risorsaID, CURDATE(), CURTIME(),
NULL, #cdcID, 'Login', 'Y')";
MySqlCommand cmd = new MySqlCommand(cmdText, connection);
cmd.Parameters.Add("#risorsaID", MySqlDbType.Int32).Value = idrisorsa_global;
cmd.Parameters.Add("#cdcID", MySqlDbType.Int32).Value = IDCDC;
int rowsInserted = cmd.ExecuteNonQuery();
Related
I tried to get result depending on two dates which the user checked.
I have two datetimepicker controls.
I want the user to chooses the "from" date and "to" date,
then the query get specific result.
leaving_time column type is nvarchar
This is my query:
SELECT name, mil_no, rotba, arrival_time, leaving_time, day, year
FROM dbo.Hodor_data
WHERE leaving_time BETWEEN '"+dateTimePicker1.Checked.ToString()+ "' AND '" + dateTimePicker2.Checked.ToString() + '"
Where is the mistake?
You should write parameterized queries and not using string concatenation for passing the parameters, in order to create a sql command. Using string concatenation makes you code vulnerable to sql injections.
var cmdText = #"SELECT ...
FROM dbo.Hodor_data
WHERE leaving_time BETWEEN #StartDate AND #EndDate";
var sqlCommand = new SqlCommand(cmdText, connection);
sqlCommand.Parameters.AddWithValue("#StartDate", dateTimePicker1.Value);
sqlCommand.Parameters.AddWithValue("#EndDate", dateTimePicker2.Value);
where connection is your sql connection object.
Try to use dateTimePicker1.Text in dateTimePicker1_ValueChanged event where you are using dateTimePicker2.Checked that return true or false not the value of date
Checked is a boolean property, and it is not the date. You need to use the Value Property. It is better to add parameters and explicitly specify the type so that the date format conflict is solved.
Edit: If column type in SQL server is NVARCHAR and of format MM/dd/yyyy, you need to use ONVERT(DATETIME, leaving_time, 101):
conn.Open();
SqlDataAdapter dataAdapter =
new SqlDataAdapter("SELECT name, mil_no, rotba, arrival_time, leaving_time, day, year "
+ "FROM dbo.Hodor_data where CONVERT(DATETIME, leaving_time, 101) "
+ "BETWEEN #p1 AND #p2", conn);
SqlParameter fromDate = new SqlParameter("#p1", SqlDbType.DateTime2);
fromDate.Value = dateTimePicker1.Value;
SqlParameter toDate = new SqlParameter("#p2", SqlDbType.DateTime2);
toDate.Value = dateTimePicker2.Value;
dataAdapter.SelectCommand.Parameters.Add(fromDate);
dataAdapter.SelectCommand.Parameters.Add(toDate);
DataTable dt = new DataTable();
dataAdapter.Fill(dt);
dataGridView1.DataSource = dt;
conn.Close()
You should really consider changing the type of column leaving_time to be a DateTime column. This will make your life easier in querying. I can't really see any advantage of storing these values as text.
an error while storing date in DB (SQL server 2005) using C#
I am using,
DateTime mydate = DateTime.Now;
insert into mytablename (appdate) values('"+mydate.ToShortDateString()+"');
bt its showing error when I run the query
also tried,
mydate.ToShortDateString().ToString("dd-MMM-yyyy HH:mm:ss") in C# , still showing error in editor only.
How do I store 'date' in SQL Server 2005 using C# query
Use parameterized SQL, and set the value into the parameter:
string sql = "insert into tablename (appdate) values (#appdate)";
using (var connection = new SqlConnection(...))
{
connection.Open();
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.Add("#appdate", SqlDbType.DateTime).Value
= DateTime.Now;
int rowsInserted = command.ExecuteNonQuery();
// TODO: Validation of result (you'd expect it to be 1)
}
}
You should always use parameterized SQL when you have data to include in the request to the database. This avoids SQL injection attacks and data conversion issues, as well as keeping your code cleaner.
You should also consider whether you really want it to be the local date/time or the UTC date/time. For example, you might want to use DateTime.UtcNow instead.
Your query tries to insert a string in a DateTime field. And of course it doesn't work.
The correct way to insert is through a parametrized query like this
string insertSQL = "insert into mytablename (appdate) values(#dt)";
SqlCommand cmd = new SqlCommand(insertSQL, con);
cmd.Parameters.AddWithValue("#dt", mydate);
cmd.ExecuteNonQuery();
Here I assume that the connection is already initialized and opened
I have a query which fetches the information from sql server on datematch.
I have searched a lot about SQL Server date string, I just want to match with the date and get the data from database. Also I am using SQL Server 2005, I want to fetch the date and take the time out of it?
Can anybody help me in that... I am new to C#
Here is my query.
return "select Timein, Timeout from Attendance where E_ID = " + E_ID + " and Date = " + DateTime.Now.ToShortDateString();
use the sql server CONVERT function to convert the input date param to time
Change your query to accommodate any one of the below CONVERT function
SQL query to convert Time format into hh:mm:ss:
select convert(varchar, <<dateparam>>, 108)
SQL query to convert Time format into hh:mi:ss:mmm(24h):
select convert(varchar, <<dateparam>>, 114)
You should always use parameters when querying a database - whether or not SQL injection is possible, it's just plain good practice to use parameters, and it solves some of the thorny how many quotes and which kind do I need here to make it a valid SQL statement questions, too.
So try something like:
string sqlStmt = "SELECT Timein, Timeout FROM dbo.Attendance " +
"WHERE E_ID = #ID AND Date = #Date";
using(SqlConnection conn = new SqlConnection("your-connection-string-here"))
using(SqlCommand cmd = new SqlCommand(sqlStmt, conn))
{
// set up parameters
cmd.Parameters.Add("#ID", SqlDbType.Int).Value = E_ID;
cmd.Parameters.Add("#Date", SqlDbType.DateTime).Value = DateTime.Now.Date;
// open connection, read data, close connection
conn.Open();
using(SqlDataReader rdr = cmd.ExecuteReader())
{
while(rdr.Read())
{
// read your data
}
rdr.Close();
}
conn.Close();
}
Im trying to get the date and the time using C# , and then insert it into a smalldatetime data type in SQL SERVER.
This is how I try to do it :
DateTime date = DateTime.Now;
sql = "INSERT INTO YTOODLE_LINKS (YTOODLE_LINKS.TASK_ID,YTOODLE_LINKS.LINK_TITLE,YTOODLE_LINKS.LINK_DESC,YTOODLE_LINKS.LINK_PATH,YTOODLE_LINKS.USER_ID,YTOODLE_LINKS.LAST_USER_EDIT)VALUES (1,'','','',2,'1',"+ date +")";
dataObj = new DataObj();
dataObj.InsertCommand(sql);
connection = new SqlConnection(conn);
connection.Open();
cmd = new SqlCommand(sql, connection);
cmd.ExecuteNonQuery();
connection.Close();
and then then it gives me : "Incorrect syntax near '16'."
I guess it refers to my current time , which is 16:15 right now..
I would suggest using parameters. cmd.Parameters.AddWithValue("#date", date.toString); The AddWithField will take care of the proper conversion.
Your InsertSQL statment becomes:
sql = "INSERT INTO YTOODLE_LINKS (YTOODLE_LINKS.TASK_ID,YTOODLE_LINKS.LINK_TITLE,YTOODLE_LINKS.LINK_DESC,YTOODLE_LINKS.LINK_PATH,YTOODLE_LINKS.USER_ID,YTOODLE_LINKS.LAST_USER_EDIT)VALUES (1,'','','',2,'1',#date)";
It doesn't work for 2 reasons:
Your date parameter needs to call date.ToString()
You must add single quotes before and after the date string is inserted in your inline query as so:
sql = "INSERT INTO YTOODLE_LINKS (YTOODLE_LINKS.TASK_ID,YTOODLE_LINKS.LINK_TITLE,YTOODLE_LINKS.LINK_DESC,
YTOODLE_LINKS.LINK_PATH,YTOODLE_LINKS.USER_ID,YTOODLE_LINKS.LAST_USER_EDIT)
VALUES (1,'','','',2,'1','"+ date +"')";
But the above strategy is not good because it exposes you to SQL Injection attacks by concatenating strings the way you are doing it and also because you have to worry about adding single quotes, etc., etc.
A better approach is to use parameters as so:
sql = "INSERT INTO YTOODLE_LINKS (YTOODLE_LINKS.TASK_ID,YTOODLE_LINKS.LINK_TITLE,YTOODLE_LINKS.LINK_DESC,
YTOODLE_LINKS.LINK_PATH,YTOODLE_LINKS.USER_ID,YTOODLE_LINKS.LAST_USER_EDIT)
VALUES (#First,#Second,#Third,#Fourth,#Fifth,#Sixth,#YourDate)";
cmd.Parameters.AddWithValue("#First", 1);
// ... and so on
cmd.Parameters.AddWithValue("#YourDate", date);
Now you don't have to worry about sql injection attacks or adding single quotes to some parameters depending on the data type, etc. It's all transparent to you, you are safer and the database engine will be able to optimize the execution plan for your query.
Here is the query:
string query = #"INSERT INTO session (PK_Id, user_id, login_time, machine_ip, machine_fingerprint)
VALUES (UUID(), #UId, #LogInTime, #MIp, #MFingerPrint);
";
Now I need this last inserted id back, which is a UUID generated by MySQL. As far as I read there is no select_last_insert_id() function for UUIDs!! And I read for php you could assign UUID() function first to a variable and then return that value. But how to go about that in C#?
Something like this, but not exactly:
string query = #"INSERT INTO session (PK_Id, user_id, login_time, machine_ip, machine_fingerprint)
VALUES (#UUID = SELECT UUID(), #UId, #LogInTime, #MIp, #MFingerPrint);
"; //how to do this here?
Here is more of my code:
string query = #"INSERT INTO session (PK_Id, user_id, login_time, machine_ip, machine_fingerprint)
VALUES (#UUID = SELECT UUID(), #UId, #LogInTime, #MIp, #MFingerPrint);
";
try
{
if (_conn.State != ConnectionState.Open)
_conn.Open();
MySqlCommand cmd = new MySqlCommand(query, _conn);
cmd.Parameters.AddWithValue("#UId", Utility.usr.Id);
cmd.Parameters.AddWithValue("#LogInTime", DateTime.Now);
cmd.Parameters.AddWithValue("#MIp", GetMachineIP());
cmd.Parameters.AddWithValue("#MFingerPrint", GetHardwareFingerPrint());
var s= Convert.ToString(cmd.ExecuteScalar()); //this returns an empty string :(
//I need to get it to any .NET data type, string, or Guid or byte[] or anything.
But I need this datatype of s to be used in another WHERE clause in a query like this:
string query = #"UPDATE session SET logout_time = #LogOutTime
WHERE user_id = #UId AND PK_Id = #SessionId";
try
{
if (_conn.State != ConnectionState.Open)
_conn.Open();
MySqlCommand cmd = new MySqlCommand(query, _conn);
cmd.Parameters.AddWithValue("#UId", Utility.usr.Id);
cmd.Parameters.AddWithValue("#SessionId", s);
cmd.Parameters.AddWithValue("#LogOutTime", DateTime.Now);
cmd.ExecuteScalar();
Here #"SessionId" is the UUID field in the same table. So basically, how can I get the MySQL varbinary field in C# so that I could use that type to update by specifying WHERE in another query?
In MySQL table the UUID field is varbinary (I hope to see some solution that is not another php link or that is not asking me to switch to char datatype in the database :) ).
Edit: The problem here is we have already added plenty of UUIDs generated by MySQL into the table, so I'm a bit apprehensive about changing MySQL UUID to .NET Guid. If that's the only workaround, I'll consider that. Just that this is the first time we needed the inserted UUID value back so that I can update in another query another point of time.
A sub question: Is .NET Guid exactly the same thing as MySQL UUID?
You can use the Guid type which is the MS implementation of UUID. You should be aware that when inserting data into the DB, you may need to convert the Guid to ByteArray if the MySQL driver isn't familiar with handling Guid's. See Store GUID in MySQL from C# for an example of this.
I think you can go ahead with your earlier implementation without having to rely on MS Guid, but I fear I am too late :)
string query = #"INSERT INTO session (PK_Id, user_id, login_time, machine_ip, machine_fingerprint)
VALUES (UUID(), #UId, #LogInTime, #MIp, #MFingerPrint);
SELECT PK_Id FROM session WHERE login_time=#LogInTime AND machine_fingerprint=#MFingerPrint; //or something similar which gives you the exact same id - UUID
";
try
{
if (_conn.State != ConnectionState.Open)
_conn.Open();
MySqlCommand cmd = new MySqlCommand(query, _conn);
cmd.Parameters.AddWithValue("#UId", Utility.usr.Id);
cmd.Parameters.AddWithValue("#LogInTime", DateTime.Now);
cmd.Parameters.AddWithValue("#MIp", GetMachineIP());
cmd.Parameters.AddWithValue("#MFingerPrint", GetHardwareFingerPrint());
MySqlDataReader r = cmd.ExecuteReader();
if (r.Read()) //ensure if it is read only once, else modify your `WHERE` clause accordingly
{
var s = (Guid)r[0];
}
//or even (Guid)cmd.ExecuteScalar() would work
Now you can query in update like this:
string query = #"UPDATE session SET logout_time = #LogOutTime
WHERE user_id = #UId AND PK_Id = #SessionId";
try
{
if (_conn.State != ConnectionState.Open)
_conn.Open();
MySqlCommand cmd = new MySqlCommand(query, _conn);
cmd.Parameters.AddWithValue("#UId", Utility.usr.Id);
cmd.Parameters.AddWithValue("#SessionId", s.ToByteArray());
cmd.Parameters.AddWithValue("#LogOutTime", DateTime.Now);
cmd.ExecuteNonQuery();
Note: Here I have converted the Guid variable s to byte array before querying. This is important, in WHERE clause, be it UPDATE or SELECT statements in query. I would ask you to move to binary field in MySQL table from varbinary.
Edit: If your table would grow dramatically large then inserting and selecting is a bad idea since SELECT query is an additional query being run. In that case #PinnyM's choice is better. I really do not think MySQL or any other database would have a default way to give back "custom" inserted ids which are not something database generated. So in short I advice you to not go for this..
Edit2: See this answer for getting binary value to .NET datatype. Sometimes casting do not work depending on MySQL .NET connector version..