So I am creating a search function within my windows form that will allow the user to search for records based on what they have entered into the textbox. I have working code for finding records based off of every filter but the DateTime one. for example:
if (customerID_rb.Checked == true)
{
sqlQuery = "SELECT CustomerID, CustomerName, Telephone, DateAndTime, Status, Description from Calls WHERE CustomerID = " + item;
//'item' is the text in the textbox
UsingCommand(conn, table, sqlQuery);
return table;
}
private static void UsingCommand(SqlConnection conn, DataTable table, string sqlQuery)
{
using (SqlCommand cmd = new SqlCommand(sqlQuery, conn))
{
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
da.Fill(table);
}
}
This will show the records containing the user entered text in the CustomerID column.
However I cannot quite figure out how to do the same but for DateTime. I know that in SQL you type 'WHERE 'DateTime = ...' but no matter how I try to reword the query string I just cannot get it to work.
The error I am getting is : 'SqlException was unhandled: An expression of non-boolean type specified in a context where a condition is expected, near 'DateAndTime'.
Code:
sqlQuery = "SELECT CustomerID, CustomerName, Telephone, DateAndTime, Status, Description from Calls WHERE DateTime DateAndTime = '" + item +"'";
I have tried with and without the DateTime and in multiple different orders, if anyone can help me with this it would be greatly appreciated!
Thanks
Edit:
Ok... I messed up a little. I wrongly assumed you would need the DateTime. However, I may have been thrown off into thinking that because I get thrown an exception if I input the date and time wrong. Thanks! :)
You should never concatenate parameters into a SQL string.
It leaves you vulnerable to SQL injection attacks.
It creates performance problems, as each unique value will create a new SQL query, having a different hash for the query, which defeats the execution-plan caching mechanism of the query engine.
For date values, the ordering of y/m/d, d/m/y, or m/d/y string formats can be different depending on the current culture settings, the OS globalization settings, and the database server's globalization settings. If they're not all in sync, then you could end up with random weirdness like mistaking January 3rd for March 1st.
Instead, you should always parameterize your queries! The query gets a placeholder for the value, and then you add the value using a separate parameter. I'm not going to give you an example here, as it takes very little time to search for this on your own and there have already been hundreds of posts on this here on S.O.
You don't need to specipy the datatype DateTime, Just write the query with column name only like
sqlQuery = "SELECT CustomerID, CustomerName, Telephone, DateAndTime, Status, Description from Calls WHERE columnname = '" + item +"'";
Generally speaking, best would be to add sql parameters, but in string format:
" ... WHERE DateAndTime = '" + item.ToString("yyyyMMdd") +"'"
The yyyyMMdd should be safe to use in all cultures.
The above is assuming, you have to search a date, not including time. Mostly times are only searched on with greater or smaller than.
Additional, if the date field itself contains time, and you only want to search the date:
".... WHERE cast(DateAndTime as date) = '" + item.ToString("yyyyMMdd") +"'"
Related
I made a programm, which shows a table from my database.
The Statement looks like that:
string sql = ("select CCase.RefNo AS Az, EventTemplate.EventCode AS
Vorgang from ikaros.CCase join ikaros.Event on CCase.ID =
Event.CCaseID join ikaros.EventTemplate on Event.EventTemplateID =
EventTemplate.ID where EventTemplate.EventCode='IRVB' and
Event.EventDate ='2014-07-03' order by CCase.RefNo ASC");
Now with
Event.EventDate='2014-07-03'
I get the table of that Date which is given in the SELECT Statement.
But I want give the user the opportunity to give a other Date in a Textbox.
The Textbox should change the Date in the Statement.
I looked here:
Try 1
Try 2
But it's not the same issue which I have.
If this is a duplicate and I was just to silly to find it, please tell me.
The added link in question shows your are using WPF So,
If your date is coming from TextBox then you should use TextBox.Text property to read date from user input like
var date = TextBox1.Text;
OR
If you used DatePicker then you can use DatePicker.SelectedDate.Value.Date property to read user input
var date = DatePicker1.SelectedDate.Value.Date;
And then pass this to sql query like
string sql = ("select ... where EventTemplate.EventCode='IRVB' and
Event.EventDate ='"+ date +"' order by CCase.RefNo ASC");
Note: Always use prepared statements (parameterized query) to prevent sql injection attack.
I m not sure that you are using ADO.NET but your paramterized query look like
string sql = ("select ... where EventTemplate.EventCode='IRVB' and
Event.EventDate = #date order by CCase.RefNo ASC");
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("#date", date);
I'm having problems with some code I'm trying to write. I'm doing something for suppliers orders, so I have a table which is named "encomendas_fornecedores" with a autoincrement field before the key that is the code of sale which consists in a EF before the number(which is a text field).
Here is the code:
connection.Open();
OleDbCommand comando1 = new OleDbCommand();
OleDbCommand comando2 = new OleDbCommand();
OleDbCommand comando3 = new OleDbCommand();
comando1.Connection = connection;
comando2.Connection = connection;
comando3.Connection = connection;
comando1.CommandText = "INSERT INTO encomendas_fornecedores (cod_encomenda_forn, cod_metodo, cod_forn, total_pagar_forn) VALUES('FO', '" + txtcodmetodo.Text + "', '" + txtcodforn.Text + "', '" + lbltotalapagar.Text + "'); ";// insert into table the values with a FO to cod
comando1.ExecuteNonQuery();
comando2.CommandText = "Select MAX(num_encomenda) From encomendas_fornecedores;";// selecting maximum num encomenda so I can isolate it and add to a text before(btw I do this in php/sql no problems
int numero = Convert.ToInt32(comando2.ExecuteScalar());//max num_encomenda
string codencomendaforn= "EF"+Convert.ToString(numero);// sales code completed
comando3.CommandText = "UPDATE encomendas_fornecedores SET cod_encomenda_forn = '"+codencomendaforn+"' WHERE num_encomenda = '"+ numero +"';";//query that is giving me the problems, it says something like "type of data incorrect in data expression"
comando3.ExecuteScalar();//giving me error this line
connection.Close();
But now here's the catch the cod_encomenda_forn is text and the num_encomenda auto increment as it is in the sql, and I tried to show the query in a textbox to see if its anything is wrong but nothing seems wrong.
"UPDATE encomendas_fornecedores SET cod_encomenda_forn = '"+codencomendaforn+"' WHERE num_encomenda = **'**"+ **numero** +"**'**;";//query that is giving me the problems,it says something like "type of data incorrect in data expression"
You are passing a string numero to a where statement that seems like it is expecting a number. As long as it is numeric it should work, but definitely not gauranteed to work. Second you are passing anothercodencomendaforn string to encomenda what is encomenda 's data type?
It appears that you are not handling potential datatype differences between your c# code and your SQL query. In addition single quoting '' around a value in a SQL statement tells the database engines that it is a string even if that is '1234'. While SQL will automatically convert some values it doesn't always. In addition c# .net library also looks for some conversion etc. before sending the SQL statement. To fix appropriately use parameters that are data typed to the database type in the SQL table. To fix it simply in the statement figure out your data types and fix the '' single quotes appropriately.
PS the people trying to help you in the comments were being nice and telling you the professional way of keeping your job in the future when you graduate after fixing this issue.
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 am developing a gym membership program on visual studio using C# and sqlite. On every employee-log in attempt, I want the program to check for expired customers where ExpiryDate(Attribute in the table Customer) is less than today's date. this is the piece of code I used:
string sql2 = "delete from Customer where ExpiryDate<' " + DateTime.Today + " ' ";
SQLiteCommand command2 = new SQLiteCommand(sql2, m_dbConnection);
command2.ExecuteNonQuery();
Why not use SQLite built-in functions?
delete from Customer where ExpiryDate<DATE('NOW')
Aren't you missing something like
delete from Customer where ExpiryDate<DATE('NOW') AND Costumer_id=?
Use a parameterized query and your problems in converting a date to a string will evaporate
string sql2 = "delete from Customer where ExpiryDate < #td";
SQLiteCommand command2 = new SQLiteCommand(sql2, m_dbConnection);
command2.Parameters.AddWithValue("#td", DateTime.Today);
command2.ExecuteNonQuery();
Of course this is also the recommended way to avoid Sql Injections but in this case is not your main concern.
By the way, I agree with comments in your question above. Probably it is better to allow a bit of flexibility in the calculation of the deadlines. For example you could add a configuration option that set the maximum number of days allowed after the deadline and add it to the DateTime.Today value.
I have a strange problem...I have a MySql db with some columns and one of the column is date_purchased which is of type date_time.
I am using C# and made a DatetimePicker and user selects a date.
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
varDate = dateTimePicker1.Value;
}
Now the problem is I have to compare the two datetimes (one from the database and one from the User) and I should display the records that are less than the date selected by the user(varDate).
select * from orders where date_purchased < = '" + varDate + "'";
I am executing this query but i am getting an exception
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '= '12/25/2011 8:01:31 PM'' at line 1
I wrote the connection string and all and I am struck at the query.
Any Help will be much appreciated...
Thanks,
Subash
You have not given any details on what you are using to run the select query; however, if you are using the connector provided by Mysql (Connector/Net) then you should be using parameters. Which would look something like this:
String sql = "select * from orders where date_purchased < #DatePurchased";
MySqlDataAdapter adapter = new MySqlDataAdapter(sql, connection);
adapter.SelectCommand.Parameters.Add("DatePurchased", MySqlType.DateTime).Value = varDate;
adapter.Fill(dataSet);
Using parameters will ensure the values are converted and will also prevent SQL Injections
Try something like where DBdatetime < "'" + vardate + "'"
One word of caution, check the formats of the two dates. I had a problem in a previous app where the DB had seconds and milliseconds, whereas the app provided just a data and set the time to 00:00. This resulted in records for the current date not showing in the result set. Thus, I had to add 23:59 to the date to get all the records for the current day.
You can retrieve the values between the two data using the following MySQL Query
SELECT * FROM table_name WHERE dbvalue < varData