I get Syntax error (missing operator) in query expression
string strSql2 = "Select N_Serie,MacID from " + cmdb_ModelStock2.Text + " WHERE Date_Ajout = " + cmdb_Date2.Text;
I put a break a point and debugg step by step, and I see, it get the date and also the time.
could that be the problem?? If so is it possible to make it get only the date not the time.
The first thing to do is to stop constructing your SQL like that. If you really need to pick the table dynamically, you should make sure you use a whitelist of valid ones... but for the "where" clause you should use parameterized SQL - parse cmdb_Date2.Text into a DateTime, and specify that as the parameter value. Using parameterized SQL protects you from SQL injection attacks, avoids conversion issues, and makes it easier to read your SQL.
So:
string tableName = ValidateTableName(cmdb_ModelStock2.Text); // TODO: Write this!
DateTime date = DateTime.Parse(cmdb_Date2.Text); // See below
string sql = "Select N_Serie,MacID from " + tableName + " WHERE Date_Ajout = ?";
using (var command = new OleDbCommand(sql, conn))
{
// Or use type "Date", perhaps... but that would be more appropriate
// with a range. The name doesn't matter using OLE, which uses positional
// parameters.
command.Parameters.Add("Date", OleDbType.DBDate).Value = date;
// Execute the command etc
}
Note that here I'm using DateTime.Parse, but ideally you'd use a UI control which gives a DateTime directly. (We don't know what kind of UI you're using, which makes it hard to give advice here.)
Depending on what data type you're using in the database, you might want to use a BETWEEN query instead of an exact match.
you better to use parameter for date like below
string strSql2 = "Select N_Serie,MacID from " + cmdb_ModelStock2.Text + " WHERE Date_Ajout = ?";
create date time from your cmdb_Date2, for example if the date time format is "yyyy-MM-dd HH:mm" then
DateTime dt =
DateTime.ParseExact(cmdb_Date2.Text, "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture);
now you can set the parameter value like below
cmd.Parameters.Add("Date_Ajout ", OleDbType.Date).Value = dt;
execute the cmd
Related
I have a table which I want to insert data in it only once in a day
and to implement that I want to check if current date already exists in
the database by writing these lines
DateTime date = DateTime.Now;
MySqlCommand cmd = new MySqlCommand("SELECT * FROM `attendances` WHERE
`lecture_id` = '" + lecture_id + "' " +
" AND `date` = '"+date.ToShortDateString()+"' ",con);
MySqlDataReader reader = cmd.ExecuteReader();
reader.Read();
if (reader.HasRows)
MessageBox.Show("you can't insert");
else MessageBox.Show("you can insert");
The date is inserted to the database in this format xxxx-xx-xx although using the same method for inserting, and date.ToShortDateString() returns the date in this format
xxxx/x/x .
I checked inserting the date manually in the correct format but that also didn't work, I also tried using the DATE function in sql but that didn't work either.
Just apply format string date = DateTime.Now.ToString("yyyy-MM-dd")
And do not call ToShortDateString() in your SQL query
You also should use SqlParameter as your code is vulnerable for SQL injection attack.
You could also avoid using .NET's DateTime and use MySql's NOW() or UTC_DATE() instead within your query, which may be better; if the region of your code and db reside in different timezones.
i.e.
[...] " AND `date` = DATE(NOW()) ",con);
Hello i try to delete from a Table where i need to access a varchar note field and an datetimefield.
Here is the Code:
DateTime test = (DateTime)powerPlant.timestamp;
string DateUS = test.ToString("s");
string deletePowerPlant =
String.Format(
"DELETE FROM [dbo].[tblSPpowerPlants] WHERE [timestamp] = CONVERT(datetime,"+ DateUS +",111) AND [note] = {0};",
note);
SqlCommand sqlDelete = new SqlCommand(deleteComponents, sqlConnection);
sqlDeletePowerPlant.CommandType = CommandType.Text;
sqlDeletePowerPlant.CommandText = deleteComponents;
sqlDeletePowerPlant.ExecuteNonQuery();
And yes normally i would use sql parameters but i want to know how it would work without parameters just to test it out becouse somehow it must be possible. I tried to google it and with some other forum and some blogs but had no luck.
Thx for your help and sorry for my english.
EDIT
The Field timestamp is a Datetime in the table.
The note is a nvarchar in the Table. And i just want to use it once so i can say i know how to do it without parameters. I know its bad....
You'll want to make sure there is no dependency on server operating system locale. So if you use a certain format (111 in your case) in the SQL query, you should use the .NET equivalent to convert your date to a string:
string DateUS = test.ToString("yyyy/MM/dd");
For details about the formats that the CONVERT function supports, see here:
https://msdn.microsoft.com/de-de/library/ms187928(v=sql.120).aspx
As you stated yourself in the question, using a (strongly typed) SqlParameter is the preferred way to go. Failing to so so may result in sql injection vulnerabilities.
Given that note is a text column, single quotes and escaping will be required:
String.Format(
"DELETE FROM [dbo].[tblSPpowerPlants] WHERE [timestamp]=CONVERT(datetime,'{0}',111) AND [note]='{1}'",
DateUS
note.Replace("'","''").Replace(#"\",#"\\")
);
If you store time-of-day too, the comparison with = will not affect records with nonzero time component.
Put some string qualifiers in there
DateTime test = (DateTime)powerPlant.timestamp;
string DateUS = test.ToString("s");
string deletePowerPlant = String.Format("DELETE FROM [dbo].[tblSPpowerPlants] WHERE [timestamp] = CONVERT(datetime,'"+ DateUS +"',111) AND [note] = '{0}';", note);
SqlCommand sqlDelete = new SqlCommand(deleteComponents, sqlConnection);
sqlDeletePowerPlant.CommandType = CommandType.Text;
sqlDeletePowerPlant.CommandText = deleteComponents;
sqlDeletePowerPlant.ExecuteNonQuery();
But really. Use parameterized queries
I have a date and time loaded into a textbox for editing, but I need to store it as a datetime in my access database not a string and cannot remember or find the syntax to parse it in my SQL parameters... here is my code anyway...
string strSql = "UPDATE OCR SET OCR = #OCR, [OCR Title] = #OCRTitle, DeadlineDate = #DeadlineDate;";
using (OleDbConnection newConn = new OleDbConnection(strProvider))
{
using (OleDbCommand dbCmd = new OleDbCommand(strSql, newConn))
{
dbCmd.CommandType = CommandType.Text;
dbCmd.Parameters.AddWithValue("#OCRTitle", textBox6.Text);
dbCmd.Parameters.AddWithValue("#OCR", textBox5.Text);
dbCmd.Parameters.AddWithValue("#DeadlineDate", textBox7.Text);
newConn.Open();
dbCmd.ExecuteNonQuery();
}
}
You're specifying a string as the deadline date value. You should specify a DateTime instead.
You can use DateTime.Parse (or DateTime.ParseExact, or DateTime.TryParseExact) to parse the text representation if you really have to - but it would be better to use a date-based control to start with, rather than having a text representation at all.
(It's not clear what sort of application this is - WinForms, ASP.NET etc - but most GUIs have some sort of date picker these days.)
EDIT: Additionally, you need to change the order in which you add the parameters to the command such that it matches the order in which the parameters are used in the SQL statement. These are effectively positional parameters - the names are ignored. It would probably be clearer to use ? than named parameters in the SQL.
I have a MySQL database, there's a table which have column Time's Type is Nvachar(50) and its values is kind like this "05/09/2012 20:53:40:843" *(Month-date-year hour:mins:second:msecond)*
Now I want to query to get a record have Time after "10/05/2012 01:00:30 PM".
I had code in C# to converted it to "05/10/2012 13:00:30" before making a query.
My Query :
SELECT * FROM ABCDFEGH WHERE capTime > '05/10/2012 13:00:30' LIMIT 0, 1
But i got no record. So please tell me how can I can make it return record have time after the time above ???
More Info My C# code :
string tableName = "ABCDFEGH";
string date = "05/10/2012 13:00:30";
var query = "SELECT * FROM " + tableName + " WHERE capTime > '" + date + "' LIMIT 0, 1";
var cmd = new MySqlCommand(query, connection);
MySqlDataReader dataReader = null;
try
{
dataReader = cmd.ExecuteReader();
}
I'm so so so so so so sorry. I made a mistake the query must be
SELECT * FROM ABCDFEGH WHERE capTime > '05/10/2012 13:00:30' LIMIT 0, 1
This query is successful return the record i need :)
But soemhow I have mistyped it into
SELECT * FROM ABCDFEGH WHERE capTime > '05-10-2012 13:00:30' LIMIT 0, 1
Sorry again, topic close. But tks for evveryone tried :)
I recommend using the DATETIME datatype instead of NVARCHAR. Store dates in YYYY-MM-DD HH:MM:SS format, which is the native DATETIME format recognized by MySQL.
Also use date literals in the same format.
Two reasons for this recommendation: First, DATETIME takes only 8 bytes, instead of up to 150 bytes which is the potential size of a multibyte 50 character varchar.
Second, the sort order of DATETIME will be the same as the chronological order. So if you create an index on the Time column, your > comparison can benefit from the index. Your query will be much faster as a result.
Use TIMESTAMPDIFF()
Schema
CREATE TABLE ABCDFEGH (`right` varchar(3), `time` datetime);
INSERT INTO ABCDFEGH (`right`, `time`)
VALUES
('Yes', '2012-10-02 13:00:30'),
('No', '2012-10-15 13:00:30');
SQL Code
SELECT * FROM ABCDFEGH
WHERE TIMESTAMPDIFF(MINUTE, time, '2012-10-05 13:00:30') > 0
LIMIT 0, 1
Explanation
TIMESTAMPDIFF() returns datetime_expr2 – datetime_expr1, where datetime_expr1 and datetime_expr2 are date or datetime expressions. One expression may be a date and the other a datetime; a date value is treated as a datetime having the time part '00:00:00' where necessary. The unit for the result (an integer) is given by the unit argument.
Fiddle: http://www.sqlfiddle.com/#!2/244cc/1 datetime
Fiddle: http://www.sqlfiddle.com/#!2/063b3/1 varchar(50)
PS1: Time may be a reserved word. Please avoid using it. Else use it with backticks (`).
PS2: The format of time is YYYY-MM-DD not the reverse.
First, why did you save the dates as NVARCHAR? If you are still able to change it to DATETIME datatype and all of the records on it, much better.
But if not, you can use STR_TO_DATE.
SELECT *
FROM tableName
WHERE STR_TO_DATE(`capTime`, '%m/%d/%Y %H:%i:%s:%x') >
STR_TO_DATE('05/10/2012 13:00:30', '%c/%d/%Y %H:%i:%s')
See SQLFiddle Demo
SOURCES
STR_TO_DATE
DATE Formats
UPDATE 1
and your query is vulnerable with SQL Injection. To avoid from it
Parameterized your query
code snippet,
string tableName = "ABCDFEGH";
string date = "05/10/2012 13:00:30";
String query = "SELECT * FROM " + tableName + " WHERE STR_TO_DATE(`capTime`, '%m/%d/%Y %H:%i:%s:%x') > STR_TO_DATE(#dateHere, '%c/%d/%Y %H:%i:%s')";
using (MySqlConnection connection = new MySqlConnection("connectionStringHere"))
{
using (MySqlCommand command = new MySqlCommand())
{
command.Connection = connection;
command.CommandType = CommandType.Text;
command.CommandText = query;
command.Parameters.AddwithValue("#dateHere",date)
MySqlDataReader dataReader = null;
try
{
dataReader = cmd.ExecuteReader();
}
catch(MySqlException e)
{
// do something here
// don't suppress the error
}
}
}
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.