I am trying to get date between two dates but i get error
selection query is
DateTime startdate = Convert.ToDateTime(metroLabel8.Text);
DateTime enddate = Convert.ToDateTime(metroLabel9.Text);
SqlCommand cmd = new SqlCommand("Select [LedId],[LedName] from [Ledger] where Date>='"+startdate+"' and Date<='"+enddate+"'", con);
error is
Please, do not hardcode, use parametrized queries instead
DateTime startdate = Convert.ToDateTime(metroLabel8.Text);
DateTime enddate = Convert.ToDateTime(metroLabel9.Text);
...
// Make sql readable
string sql =
#"Select [LedId],
[LedName]
from [Ledger]
where Date >= #prmStartDate and Date <= #prmEndDate";
// wrap IDisposable (SqlCommand) into using
using (SqlCommand cmd = new SqlCommand(sql, con)) {
cmd.Parameters.Add("#prmStartDate", SqlDbType.DateTime).Value = startDate;
cmd.Parameters.Add("#prmEndDate", SqlDbType.DateTime).Value = endDate;
...
}
Hardcoded queries are
Prone to Sql injection
Brittle (depends on, say, datetime formatting - the gap you fell into)
Slow: there's performance decrease since RDBMS has to parse the query each time it executes it
The best way to handle conversion is to let the provider handle that for you:
DateTime startdate = Convert.ToDateTime(metroLabel8.Text);
DateTime enddate = Convert.ToDateTime(metroLabel9.Text);
SqlCommand cmd = new SqlCommand("Select [LedId],[LedName] from [Ledger] where Date >= #startDate and Date <= #endDate", con);
SqlParameter startParameter = cmd.Parameters.Add("#startDate ",
System.Data.SqlDbType.DateTime);
SqlParameter endParameter = cmd.Parameters.Add("#endDate",
System.Data.SqlDbType.DateTime);
startParameter.Value = startdate;
endParameter.Value = enddate;
cmd.Parameters.Add(startParameter);
cmd.Parameters.Add(endParameter);
Don not concatenate strings when building up your SQL queries, this is prone to SQL injection and is considered a security issue in your code.
Without seeing your inputs, I would suggest you use parameterized SQL in your C# or create a stored procedure to accept DATETIME parameters. You shouldn't use hardcoded SQL queries - in short: they are prone to attack and not optmized in SQL.
A really easy way to do this would be to use the Dapper.NET object mapper.
In SQL, you could do:
CREATE PROCEDURE return_led_for_dates
#startdate DATETIME,
#enddate DATETIME
AS
BEGIN
SELECT
[LedId],
[LedName]
FROM
[Ledger]
WHERE
Date BETWEEN #Startdate AND #Enddate
END
And with Dapper, your C# could then be:
DateTime startdate = Convert.ToDateTime(metroLabel8.Text);
DateTime enddate = Convert.ToDateTime(metroLabel9.Text);
var LED = this.Connection.Query<LED>(
"return_led_for_dates",
new {
StartDate = startdate,
EndDate = enddate
},
commandType: CommandType.StoredProcedure);
You would need an LED class too:
public class LED
{
int LedId {get; set;},
string LedName {get; set;}
}
Finally, this assumes that there is no issue with your text field conversions, you should use DateTime.TryParse. You can then bullet proof your code, and ensure the field is corretly parsed. Like:
DateTime startDate;
DateTime endDate;
if (DateTime.TryParse(Convert.ToDateTime(metroLabel8.Text), out startDate) && DateTime.TryParse(Convert.ToDateTime(metroLabel9.Text), out endDate))
{
// Your data code.
}
Related
I have a method that requires 3 string so:
public <List> MethodName(string date1, string date2, string number)
{
//
}
in my database date1 and date2 are stored as DateTime and number is stored as Int so how would I write a SQL query that will search based on these three parameters?
I have converted my date1 and date2 like this:
DateTime firstdate = Convert.ToDateTime(date1);
string fdate = firstdate.ToLongDateString();
DateTime seconddate = Convert.ToDateTime(date1);
string sdate = seconddate .ToLongDateString();
My SQL query is:
SELECT * From TableName
WHERE [Time] > #date1 AND
[Time] < #date2 AND [StaffCode] =#StaffCode;
command.Parameters.AddWithValue("#date1", fdate);
command.Parameters.AddWithValue("#date2", sdate );
command.Parameters.AddWithValue("#StaffCode", number);
conn.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{ get the data ...}
I am sure that my SQL query is wrong.
Since your database columns are already strongly typed, just ensure that your C# parameters are typed as System.DateTime and int (System.Int32) respectively before binding them to your query. Your sql is then simply:
SELECT col1, col2, col3
FROM TableName
WHERE [Time] > #date1 AND
[Time] < #date2 AND [StaffCode] =#StaffCode;
If you allow for inclusive dates, you can use BETWEEN, i.e.
WHERE [Time] BETWEEN #date1 AND #date2
AND [StaffCode] = #StaffCode
i.e. avoid the need to convert a Date to a string altogether. Wherever possible, try and keep a strong type system all the way through your code, both C# and SQL - this will save a lot of pain during conversion. e.g. if possible, see if you can change the signature to:
public List<MethodName>(DateTime date1, DateTime date2, int number)
{
// Bind the DateTimes, not a string!
command.Parameters.AddWithValue("#date1", date1);
command.Parameters.AddWithValue("#date2", date2);
command.Parameters.AddWithValue("#StaffCode", number);
Edit Don't use SELECT * - use SELECT Col1, Col2, ...
Conversion:
DateTime firstdate = Convert.ToDateTime(date1);
string fdate = firstdate.ToString("yyyy-MM-dd");
DateTime firstdate2 = Convert.ToDateTime(date2);
string fdate2 = firstdate2.ToString("yyyy-MM-dd");
SQL Query:
#"SELECT * From TestTable WHERE Time BETWEEN CONVERT(Date,#date1) AND CONVERT(Date,#date2) AND StaffCode=CONVERT(int,#StaffCode)"
command.Parameters.AddWithValue("#date1", fdate);
command.Parameters.AddWithValue("#date2", fdate2);
command.Parameters.AddWithValue("#StaffCode", number);
I am capturing the time in the text box (by using AJAX calender extender)
the time in the string is 12/10/2013, but when I assign the string to a datetime object it is converted into 12/10/2013 12:00:00 AM.
I want to use the date to filter the records in the database using the query below. Please help
string date1 = txtDate1.Text;
DateTime date = DateTime.ParseExact(txtDate1.Text, "MM/dd/yyyy",
System.Globalization.CultureInfo.InvariantCulture);
string strQuery = "SELECT Story.UserName,Story.StoryId,COUNT(Likes.StoryID) AS NumberOfOrders
FROM Likes LEFT JOIN Story ON Likes.StoryId=Story.StoryId and liked=" + date1 + "
GROUP BY Story.StoryId,Story.UserName order by NumberOfOrders DESC ;";
It's generally not a good idea to pass dates as strings in your queries because you will most likely run into formatting issues - leave it up to the Framework you are using decide on what the best format is.
In your circumstances, you can do this by using SqlParameters e.g.
DateTime date = DateTime.ParseExact(txtDate1.Text, "MM/dd/yyyy", CultureInfo.InvariantCulture);
string strQuery = "SELECT Story.UserName, Story.StoryId, COUNT(Likes.StoryID) AS NumberOfOrders
FROM Likes LEFT JOIN Story ON Likes.StoryId=Story.StoryId and liked=#dateTime
GROUP BY Story.StoryId,Story.UserName order by NumberOfOrders DESC";
using (SqlConnection connection = new SqlConnection("..."))
{
using (SqlCommand cmd = new SqlCommand(strQuery, connection))
{
cmd.Parameters.AddWithValue("#dateTime", date);
connection.Open();
SqlDataReader reader = cmd.ExecuteReader();
...
}
}
Another important reason to use parameters when writing raw SQL is to ensure your user input is correctly sanatized and safe to pass to the DB. Failure to do this can leave you open to various exploitations such as SQL Injection.
Instead of DateTime object you can use Date object.
DateTime is an integer interpreted to represent both parts of DateTime (ie: date and time). You will always have both date and time in DateTime.
ex:
DateTime.Now.ToString("MM/dd/yyyy");
I have an italian format datetime string like this:
23/03/2012
the sql command of this update is this in the datetime part:
DateTime.ParseExact(Reg_tes.Text, "dd/MM/yyyy", CultureInfo.InvariantCulture)
This works on my Sql server(Italian language) but if i make this on my server(English language) gives me this error:
"the conversion of a varchar data type to a datetime data type
resulted in an out-of-range value"
How can I resolve this?
You should always use parameterized queries to prevent sql-injection and localization issues like this.
So i assume that you are passing this datetime as string to the database.
using(var con = new SqlConnection("connection-string"))
using(var cmd = new SqlCommand("UPDATE dbo.TableName SET DateColumn=#DateColumn WHERE PK=#PK", con))
{
DateTime reg_tes = DateTime.ParseExact(Reg_tes.Text, "dd/MM/yyyy", CultureInfo.InvariantCulture);
cmd.Parameters.AddWithvalue("#DateColumn", reg_tes);
// other parameters ...
con.Open();
int affected = cmd.executeNonQuery();
}
In my SQL stored procedure:
#StartDate as smalldatetime,
#EndDate as smalldatetime
In my C# code:
StartDate = new DateTime(1901,01,01,00,00,00);
EndDate = new DateTime(2200,01,01,00,00,00);
var StartDate2 = StartDate.ToString("dd/MM/yyyy HH:mm:ss");
StartDate2 = DateTime.ParseExact(StartDate2, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture).ToString("dd/MM/yyyy HH:mm:ss");
StartDate = Convert.ToDateTime(StartDate2);
var EndDate2 = EndDate.ToString("dd/MM/yyyy HH:mm:ss");
EndDate2 = DateTime.ParseExact(EndDate2, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture).ToString("dd/MM/yyyy HH:mm:ss");
EndDate = Convert.ToDateTime(EndDate2);
The column is as a smalldatetime type in the db. I'm going round in the circles with this! whats the correct way to parse my Dates to the correct format for querying in the db?
UPDATE:
Changed code to this and worked fine.
SqlParameter parameter = daHoliday.SelectCommand.Parameters.Add("#StartDate", System.Data.SqlDbType.SmallDateTime);
SqlParameter parameter2 = daHoliday.SelectCommand.Parameters.Add("#EndDate", System.Data.SqlDbType.SmallDateTime);
parameter.Value = StartDate;
parameter2.Value = EndDate;
Don't convert them to string, just pass them as DateTime type object through Command Parameters.
DateTime should never be converted to string to match format of data in database table. If the datatype in table is DateTime then its always better to pass the .Net framework DateTime object as parameter to command.
DateTime startDate = DateTime.ParseExact(txtstart.Text, "yyyyMMdd", null);
DateTime endDate = DateTime.ParseExact(txtend.Text, "yyyyMMdd", null);
SqlDataAdapter adapter = new SqlDataAdapter(
"select * from Membership_det where updateDate between "+
startDate.ToString() + " and "+ endDate.ToString() +" ", con);
It gives error:
String was not recognized as a valid DateTime.When date is entered in
mm/dd/yyyy format
Well yes - you're explicitly specifying that you want to parse it in yyyyMMdd format. I don't see why you'd expect it to work if you've actually specified it in MM/dd/yyyy format. If you want to handle that instead, change your parsing code:
DateTime startDate = DateTime.ParseExact(txtstart.Text, "MM/dd/yyyy",
CultureInfo.InvariantCulture);
DateTime endDate = DateTime.ParseExact(txtend.Text, "MM/dd/yyyy",
CultureInfo.InvariantCulture);
However:
If this is parsing user input, you should use DateTime.TryParseExact instead, so you can detect errors in the input in the normal flow instead of using exceptions.
This code is very US-centric; non-US users may well find it confusing. In general you'd either be better off using one of the standard date formats (and the user's culture) or even better, using a date picker control of some form, to avoid the whole text format issue to start with.
Next you're using the values directly in the SQL statement. Don't do that. Always, always, always use parameterized SQL:
SqlDataAdapter adapter = new SqlDataAdapter(
"select * from Membership_det where updateDate between #Start and #End",
con);
adapter.SelectCommand.Parameters.Add("#Start", SqlDbType.Date).Value = startDate;
adapter.SelectCommand.Parameters.Add("#End", SqlDbType.Date).Value = endDate;
(Or create the command first and then pass that to the adapter.)
Using parameterized SQL has three benefits:
It avoids SQL injection attacks
It avoids data conversion issues (which are common with dates)
It keeps your SQL easy to read by separating the code from the data
Access DB Only
DateTime startDate = DateTime.ParseExact(txtstart.Text, "MMddyyyy", null);
DateTime endDate = DateTime.ParseExact(txtend.Text, "MMddyyyy", null);
SqlDataAdapter adapter = new SqlDataAdapter(
"select * from Membership_det where format( updateDate,'MM/dd/yyyy') between '"+
startDate.ToString("MM/dd/yyyy") + "' and '"+ endDate.Tostring("MM/dd/yyyy") +"' ", con);
Sql Server
DateTime startDate = DateTime.ParseExact(txtstart.Text, "MMddyyyy", null);
DateTime endDate = DateTime.ParseExact(txtend.Text, "MMddyyyy", null);
SqlDataAdapter adapter = new SqlDataAdapter(
"select * from Membership_det where Convert(varchar(15), updateDate,106) between '"+
startDate.ToString(dd MMM yyyy) + "' and '"+ endDate.Tostring(dd MMM yyyy) +"' ", con);