c# datatable select statement with dates - c#

i am trying to make a select statement on a datatable to get the row that is within the date range i am looking for. I am new to this an i dont quite understand how this select statement works. I tried to write this but is not working. Can you please give me a hand here. I am stuck
foundRows = dt.Select("DATE1 <= '" + date1+ "' AND DATE2 >= '" + date1+ '"');

This the Best Optimal Search Criteria I have Tested.
you having to dates.
From_Date = 12/01/2012
To_Date = 12/31/2012
and Your column in DataTable upon which you applying . (in my code 'date')
Your Select Statement will be like this.
DataRow[] rows = newTable.Select("date >= #" + from_date + "# AND date <= #" + to_date + "#");

Besides wrapping your dates with #, if date1 is a DateTime and not a string, you need to use the ToString(your date format) to get the correct sql statement. For debugging it make it easier if first you create a string containing your filter, then do the select using that string. Then you can look at the string and use that in the query builder to validate your sql.

I posted an answer on this post.
DataTable Select by exact DateTime
You can use a similar approach by using ticks to select in a range.

Using this inside an SSIS script component. I just used the example from above that included "#" around the dates. Also I converted each to string. This worked perfectly.
Just in case you want to know how I setup this up inside SSIS:
First had a data flow using the recordset destination with an Object variable to store the recordset.
in my script I included the variable as a read only.
In the main class...
public class ScriptMain : UserComponent
{
OleDbDataAdapter a = new OleDbDataAdapter();
System.Data.DataTable AwardedVacTable = new System.Data.DataTable();
...
...
then in Pre-Execute...
public override void PreExecute()
{
base.PreExecute();
a.Fill(AwardedVacTable, Variables.rsAwardedVac);
...
...
then in a custom method accessed the datatable ...
String dtFilter = "EmployeeID = " + empId.ToString() + " AND (#" + Convert.ToString(StartDate) "# <= EndDate AND #" + Convert.ToString(StartDate) + "# >= StartDate" + " OR #" + Convert.ToString(StartDate.AddDays((double)numDays)) + "# >= StartDate AND #" + Convert.ToString(StartDate.AddDays((double)numDays)) + "# <= EndDate)";
DataRow[] Overlaps = AwardedVacTable.Select(dtFilter);

expression = "Date > #2015-1-1#";
DataRow[] foundRows = table.Select(expression);
与
select * from tablename where Date>'2015-1-1'

Related

Access Data type mismatch of date in sql query

I am trying to get a list of orders from my access database that were ordered between 2 dates.
this is my query:
"SELECT * FROM Orders WHERE OrderDate >= '#" + DateTime.Parse(txtDate.Text) + "#' AND OrderDate <= '#" + DateTime.Parse(txtEndDate.Text) + "#'";
the 2 textboxes recieve the dates directly from 2 ajax calendar extenders. i have already made sure that the first date is before the second, and i had made sure that the data inserted to the database was also inserted like '#"+date+"#', but i "still data type mismatch in query expression".
can anyone try and identify a problem with my query?
Assuming you have data like this:
var txtDate = new { Text = "2020-08-01" };
var txtEndDate = new { Text = "2020-08-01" };
your query might look like this:
var fromDate = DateTime.ParseExact(txtDate.Text, "yyyy-MM-dd",
CultureInfo.InvariantCulture).ToString("yyyMMdd");
var toDate = DateTime.ParseExact(txtEndDate.Text, "yyyy-MM-dd",
CultureInfo.InvariantCulture).ToString("yyyMMdd");
var query =
$"SELECT * FROM Orders WHERE OrderDate>='{fromDate}' AND OrderDate<='{toDate}'";
or the last part can be:
var query =
$"SELECT * FROM Orders WHERE OrderDate BETWEEN '{fromDate}' AND '{toDate}'";
It is the octothorpes that are delimiters for date expressions, not single quotes. And the formatted text expression for a date value should be forced. Thus:
"SELECT * FROM Orders WHERE OrderDate >= #" + DateTime.Parse(txtDate.Text).ToString("yyyy'/'MM'/'dd") + "# AND OrderDate <= #" + DateTime.Parse(txtEndDate.Text).ToString("yyyy'/'MM'/'dd") + "#";
That said, look up how to run queries with parameters. It takes a few more code lines but is much easier to debug and get right.
You should use a parameterized query for both security and for type safety
Access database queries use ? as a placeholder for the parameters you pass.
OleDbCommand command = new OleDbCommand();
// I assume you have an oledb connection object and it is in open state
command.Connection = myConnection;
command.CommandText = "SELECT * FROM Orders WHERE OrderDate >= ? AND OrderDate <= ?";
// Please note that the name of the parameters are redundant and not used
command.Parameters.AddWithValue("StartDate", DateTime.Parse(txtDate.Text));
command.Parameters.AddWithValue("EndDate", DateTime.Parse(txtEndDate.Text));
// You can also use your data adatper. This is just an example
command.ExecuteReader();

Update database with date format

I found some threads here in the forum related to this problem but they didn't help me. I just want to update my database with a date value. These come from a Textfile (written there as 2014-10-02 for example). Now I tried this (which was mentioned in the other threads):
String connectionQuery = form1.conString.Text;
SqlConnection connection = new SqlConnection(connectionQuery);
SqlCommand sqlComInsert = new SqlCommand(#"INSERT INTO [" + form1.tableName.Text + "] ([" + form1.CusId.Text + "],["+ form1.date.Text +"],[" + form1.cusName.Text + "]) VALUES('" + cusId[i] + "',convert(date,'" + date[i] + "',104),'" + "','" + cusName[i] + "')", connection);
sqlComInsert.Connection.Open();
sqlComInsert.ExecuteNonQuery();
sqlComInsert.Connection.Close();
Now when I leave the "'" out ("',convert / "',104)) he tells me that the syntax is incorrect near 2013 (the beginning of my date). When I write it like above then I get:
String or binary data would be truncated.
What is this? I tried also to convert the date with:
for (int i = 0; i < typeDelDate.Count; i++)
{
unFormatedDate = date[i];
formatedDate = unFormatedDate.ToString("dd/MM/yyyy");
dateFormat.Add(formatedDate);
}
but I get still the same errors. How can I update my values? the column type is "date".
Use parametrized queries instead of slapping strings together:
var commandText = "insert (column) values (#dt);";
var cmd = new SqlCommand(commandText, connection);
cmd.Parameters.AddWithValue("dt", DateTime.ParseExact(dateString, "yyyy-MM-dd"));
cmd.ExecuteNonQuery();
Do not pass values into queries by adding strings - if possible, you should always use parameters. It saves you a lot of trouble converting to proper values (different for different locales etc.), it's more secure, and it helps performance.

Error with Query from the System Table

I want ask you one problem that I have with one query to the System table.
This is the code that I have wrong.
string current_query = "*[(System[TimeCreated[#SystemTime > '" + dateini + "']]) and (System[TimeCreated[#SystemTime < '" + datenext + "']])]";
Console.WriteLine(current_query);
EventLogQuery eventsQuery = new EventLogQuery(log_location, PathType.FilePath, current_query);
EventLogReader logReader = new EventLogReader(eventsQuery);
The dateini and datenext are DateTime variables.I think that the problem is that I read the table two times. But I need read two times because I need obtain the logs of the System of one full day and I think I must compare between two System Times.
Any suggestion that how remake the consult.
UPDATE:
I try this query with the same result.
string current_query = "*[(Event/System/TimeCreated/#SystemTime > " + dateini + ") and (Event/System/TimeCreated/#SystemTime < " + datenext + ")]";
Console.WriteLine(current_query);
EventLogQuery eventsQuery = new EventLogQuery(log_location, PathType.FilePath, current_query);
EventLogReader logReader = new EventLogReader(eventsQuery);
Please I need help because I don't know which is the error in the Query.
TimeCreated is of the form:
<TimeCreated SystemTime="2013-08-15T16:21:21.000000000Z" />
is your datetime correct?
Shouldn't the query be more like:
Event/System/TimeCreated/#SystemTime
See MSDN and reading-event-logs-efficiently-using-c for some examples.
EDIT
Why are you using > and lt; ? Change lt; to <
This turned out to be the problem.

XML to database and vice-versa

I can insert my XML easily into my database table, but i follow this exhausting manner as seen in my down code using LINK, which is perfectly tested. But, I wonder if I can find a way to read all my XML descendants elements of "Level" node, using iteration of all child tagnames, because when I make any change to my XML file, I would have to change my LINK code once again,and usually i'll face some errors when i use this exhausting manner. Please help improve this code:
try
{
XElement d = XElement.Parse(richTextBox1.Text.ToString());
var people = (from Level in d.Descendants("Level")
select new
{
ID = Convert.ToInt32(Level.Element("ID").Value),
Day1 = Level.Element("Day1").Value,
Day2 = Level.Element("Day2").Value,
Day3 = Level.Element("Day3").Value,
Day4 = Level.Element("Day4").Value,
Day5 = Level.Element("Day5").Value,
Day6 = Level.Element("Day6").Value,
Day7 = Level.Element("Day7").Value
}).ToList();
foreach (var item in people)
{
//Insert and Update
datacommand1.CommandText = "Insert Into MyTable(ID,Day1,Day2,Day3,Day4,Day5,Day6,Day7) values(" + item.ID + "," + "','" + item.Day1 + "','" + item.Day2 + "','" + item.Day3 + "','" + item.Day4 + "','" + item.Day5 + "','" + item.Day6 + "','" + item.Day7 + "')";
datacommand1.ExecuteNonQuery();
}
}
my XML file seems like that:
<level>
<id> 101 </id>
<Day1> task 1</Day1>
<Day2> task 2</Day2>
<Day3> task 3</Day3>
<Day4> task 4</Day4>
<Day5> task 5</Day5>
<Day6> task 6</Day6>
<Day7> task7 </Day7>
</level>
Instead of declaring one variable for each tag in the file, you may want to try to iterate over all them, extracting the name and the value for each one and composing the SQL statement at runtime from those, no matter what they are. Try something like this:
IEnumerable<XElement> items = d.Descendants("level").Elements();
string names = string.Empty;
string values = string.Empty;
foreach (XElement item in items)
{
names += item.Name + ",";
values += "#" + item.Name + ",";
IDbDataParameter parameter = datacommand1.CreateParameter();
parameter.ParameterName = "#" + item.Name;
parameter.DbType = DbType.String;
parameter.Value = item.Value;
datacommand1.Parameters.Add(parameter);
}
datacommand1.CommandText = "INSERT INTO MyTable (" + names.Substring(names.Length - 1) + ") VALUES (" + values.Substring(values.Length - 1) + ");";
datacommand1.ExecuteNonQuery();
This builds the command on the fly, based on the XML structure, and fills its parameters with the data there. But doing so relies on the fact that the table structure will be exactly the same as in the file, and still needs manual schema updating when the structure changes, but as long as they're in sync it should be fine.
EDIT
About datatypes, there are 2 choices I can think of. Leave as it is, sending everything as strings no matter what, and rely on the DB engine to parse, validate and turn those into numbers (depending on what DB you're using, that may be possible or not, but I guess it's not rare to see). Or modify the code to separate the special fields apart from the loop (and excluding from it) and add those one by one, specifying their types accordingly. This is easy to do if the numeric columns are fixed, like the ID, and everything else is text.

I cannot select a range of dates in my query I get no answer for my Between query

I am trying to send this message through C# to an access database. The user input are two dates selected through a datePicker. The date picker itself is selected as short format. and the access db field is also selected as a short date time. following is my code
"SELECT PLADS,COUNT(*)AS Total FROM OptagetPladser " +
"WHERE( Dato Between #" + date_1 + "# AND #" + date_2 + "# AND Optaget= 0) " +
"GROUP BY PLADS HAVING Total >= " + diffResult;
The problem seems to be the between statement. I have tested using >= date 1 and i get all the results greater than date 1. I then try with just the results <= date 2 and this works but >=date 1 and and <= date 2 gives an empty answer
Try using parameters:
StringBuilder sb = new StringBuilder();
sb.AppendLine("SELECT PLADS, COUNT(*) AS Total FROM OptagetPladser");
sb.AppendLine("WHERE ((Dato Between ? AND ?) AND Optaget= 0)");
sb.AppendLine("GROUP BY PLADS HAVING Total >= ?");
Using an established connection:
using (OleDbCommand cmd = new OleDbCommand(sb.ToString(), cn)) {
cmd.Parameters.AddWithValue("?", date_1);
cmd.Parameters.AddWithValue("?", date_2);
cmd.Parameters.AddWithValue("?", diffResult);
using (OleDbDataReader rdr = cmd.ExecuteReader()) {
while (rdr.Read()) {
// do something
}
}
}
For OleDb, the parameters are based on an index of when they appear in the SQL string, hence, the "?" values have to be entered in the same order they appear in the query string.
Are you sure you can use a column alias in your Having clause?
HAVING Count(*) >= " + diffResult;
Suggestion: Copy and paste the sql string you built with all the values into the query designer and make sure it runs there.
But what if you are using an OleDbDataAdapter() instead of OleDbCommand() so that you can get the data into a datagridview in windows forms?

Categories