Check Time Overlap In SQL - c#

I am trying to check two interval of time, the first is know in the code as two DATETIME instances Start_Time and End_Time , and the second interval i retrieve from the database, How i can check for Minutes in case the Hours are equal, here is what i am trying to write
Select * FROM MY_TABLE
WHERE " ( "+ Start_Time + "<= IF(HOUR(DB_End_Time)=0, 24, HOUR(DB_End_Time) ) AND" +
" IF(HOUR(DB_Start_Time)=0, 24, HOUR(DB_Start_Time) ) <= " + End_Time + " ) "+
" OR "+
" ( "+ Start_Time +"<= IF(HOUR(DB_Start_Time)=0, 24, HOUR(DB_Start_Time))AND " +
" IF(HOUR(DB_End_Time)=0, 24, HOUR(DB_End_Time) ) <= " + End_Time+" ) ;"+
I tried things like Between and >= <= for the datetime it self , but it keep getting me an error and ask to check sql version!
This works fine with hours, any one knows how to include IF statement or something to get it work fine with minutes as well !?

If you have actual datetimes to work with, I think you are making this too complicated by trying to isolate hours, minutes, seconds, etc.
Try something of this nature:
select *
from MY_TABLE
where #Start_Time < DB_End_Time
and #End_Time > DB_Start_Time
This will check for any overlap, but not for consecutive intervals. As in, I don't think 10-11 and 11-12 overlap, but you can change < ... > to <= ... >= to account for that if you wish.
Also, as has been mentioned, please use a parameterized query from your app rather than your concatenated string which is vulnerable to sql injection attacks.

Related

Return DB results within Date Range

In my view, I have an input and select tags for the user to enter a start and end date.
When submitted, The controller will search the Model/Database and return entries within the above range.
In my DB, the start and end dates are written as "nvarchars" and in my controller they are taken as strings
Code and Images for reference:
public ActionResult timePeriod(string time)
{
//Start: month, day, year End: month, day, year --> Numeric values
string[] times = time.Split(',');
string start = times[0] + " " + times[1] + " " + times[2];
string end = times[3] + " " + times[4] + " " + times[5];
//Sample code to test the start date
viewModel.Tasks = db.Tasks.Where(s => s.StartTime.Contains(start)).ToList();
}
a snippet of the Database values:
Are there any LINQ expression to do this?
As the dates are strings, you've nothing better other than using what you have suggested already:
viewModel.Tasks = db.Tasks.Where(s => s.StartTime.Equals(start)).ToList();
I would use Equals as that will be quicker for you. Using Contains is basically like doing a T-SQL LIKE which is much slower.
SELECT *
FROM Table
WHERE StartDate LIKE 'blah'
Using Equals will result in the following equivalent:
SELECT *
FROM Table
WHERE StartDate = 'blah'
Which is much more efficient.

How to get scheduled job time?

I have a scheduled job which runs at 12:45:00 AM. Now through SP I want to get this time. I am running this query in my SP:
EXEC msdb.dbo.sp_help_job
#job_name = N'Daily Trends',
#job_aspect = N'SCHEDULES' ;
This query shows result with a column
active_start_time
4500
Expected Output: 12:45:00 AM.
Can you please suggest how to show the time with Am/PM.
Edit: I am calling this SP from c# code. If anybody can suggest how i can convert the time in proper format in c# code will also be helpful.
As the time value seems to be stored as HHMMSS with the hour (HH) optional I think you need to check if the length of the string is four chars (or maybe if the value exceeds 115959, whichever is faster). A query like this should work:
SELECT CASE
WHEN Len(active_start_time) = 4 THEN Cast(
Dateadd(minute, active_start_time /
100, '00:00') AS TIME)
ELSE LEFT(RIGHT('0' + Cast(active_start_time AS VARCHAR), 6), 2)
+ ':'
+ Substring(RIGHT('0' + Cast(active_start_time AS VARCHAR), 6), 3,
2)
+ ':'
+ RIGHT(Cast(active_start_time AS VARCHAR), 2)
END AS [Start time]
FROM msdb..sysschedules
INNER JOIN msdb.dbo.sysjobschedules
ON msdb.dbo.sysjobschedules.schedule_id =
msdb..sysschedules.schedule_id
INNER JOIN msdb.dbo.sysjobs
ON msdb.dbo.sysjobs.job_id = msdb.dbo.sysjobschedules.job_id
WHERE msdb.dbo.sysjobs.name = 'Daily Trends'
I didn't test it with that many values but I believe it should work, or at least give you a hint on how to proceed. Accessing the msdb tables directly might be a bad idea and if I recall right, there are some views that give access to similar information and it could be better to use them.
You can use the sysjobschedules table however the date will be the same.
This blog should help parse the date/time:
http://blog.sqlauthority.com/2008/12/22/sql-server-find-next-running-time-of-scheduled-job-using-t-sql/
so, to get the data to look like a HH:MM:SS format, the following SQL would work:
SELECT LEFT(RIGHT('0' + Cast(active_start_time AS VARCHAR), 6), 2)
+ ':'
+ Substring(RIGHT('0' + Cast(active_start_time AS VARCHAR), 6), 3, 2)
+ ':'
+ RIGHT(Cast(active_start_time AS VARCHAR), 2)
FROM msdb..sysschedules

graphing non sequential data C# and mysql

I'm trying to display in a graph (Winforms/C#) the total amount from one column vs unit of time (in this case month) - so it would be a amount vs time graph. The problem is that the user would like the freedom of lets say - choosing the totals for January and June and compare them in a single graph (so the total for the month of January would be represented as a bar next to June's total's bar). I already capture the selected months (also, I have the graph control on the for) within a list but where I am really stuck is to build the mysql statement and its something like this
selectdataforGraph = "SELECT SUM(Amount_Net) AS Total FROM testingproject.incomeinformation WHERE date";
foreach (int month in selectedMonth) {
selectdataforGraph += "between '" + selected_year+ "-" + month +
"'-1 AND '" + selected_year + "-"+month+ "-31' AND";
}
I know it has some space missing and some quotation mark problems - already ran the query and I figured as much but I don't think the in-between would work because I don't know how to AND the next part of it so if a user picks May then August would be between 2007-5-01 and 2007-5-30 AND 2007-8-01 and 2007-8-30???
EDIT: didn't seem MySQL was your DB...
Definitely use a parameterized query! However... to fit in with what you have and so you can test it quickly...
I think I would use DATEPART rather than BETWEEN....
var selectdataforGraph = "SELECT SUM(Amount_Net) AS Total FROM testingproject.incomeinformation WHERE ";
var monthList = string.Join(",", selectedMonth);
selectdataforGraph += " YEAR(date) = " + selected_year;
selectdataforGraph += " AND MONTH(date) in (" + monthList + ")";

Greater than is not working in CAML query

I want to retrieve records which the users are active n last modified date is greater than lastrun date, i wrote the following CAML but doesnt seem like working. Any help is much appreciated.
camlQuery.ViewXml
= "<View><Query><Where><And><Eq><FieldRef Name='Active'/>"
+ "<Value Type='Boolean'> " + 1 + "</Value></Eq><Gt>"
+ "<FieldRef Name='_DCDateModified'/><Value Type='DateTime'>"
+ lastUpdate + "</Value></Gt></And></Where></Query></View>";
I suppose it could be a Date formatting issue. You could attempt to:
1) explicit exclude of Time portion of DateTime
2) convert in advance your Date
like this:
...<Value IncludeTimeValue='False' Type='DateTime'>" + SPUtility.CreateISO8601DateTimeFromSystemDateTime(lastUpdate) +"</Value>

Subsonic 2.2 SqlQuery with complicated clauses

I've written the following query for a resource scheduling calendar app. The query is used to find any events already scheduled on the calendar that would conflict with the event of interest:
string qry = "SELECT * FROM " + EventX.Schema.TableName +
" WHERE " +
" ( " +
" ( " +
EventX.Columns.StartTime + " >= '" + startTime +
"' AND " + EventX.Columns.StartTime + " < '" + endTime +
"' ) " +
" OR " +
" ( " +
EventX.Columns.EndTime + " > '" + startTime +
"' AND " + EventX.Columns.EndTime + " <= '" + endTime +
"' ) " +
" ) " +
" AND " +
" ( " +
EventX.Columns.EventID + " <> " + eventId +
" AND " + EventX.Columns.StatusID + " IN " +
" ( " +
(int) EventStatus.Approved + " , " +
(int) EventStatus.Completed +
" ) " +
" ) ";
QueryCommand qc = new QueryCommand(qry, EventX.Schema.Provider.Name);
EventXCollection events = new EventXCollection();
events.LoadAndCloseReader(DataService.GetReader(qc));
The above query works, but it's a freakishly ugly abomination in terms of aesthetics and I'd prefer not to leave a mess for whoever has to maintain this after me. I wrote this query after having tried and failed to get it working using a SqlQuery instead. The closest I came to getting it right before giving up on SqlQuery and writing the functional-but-ugly hack above was the following (incorrect) query:
SqlQuery qry = new Select().From(EventX.Schema.TableName);
qry.WhereExpression(EventX.Columns.StartTime).IsGreaterThan(startTime);
qry.And(EventX.Columns.StartTime).IsLessThan(endTime);
qry.OrExpression(EventX.Columns.EndTime).IsGreaterThan(startTime);
qry.And(EventX.Columns.EndTime).IsLessThan(endTime);
qry.AndExpression(EventX.Columns.EventID).IsNotEqualTo(eventId);
qry.And(EventX.Columns.StatusID).In((int)EventStatus.Approved, (int)EventStatus.Completed);
I'm working on maintaining an application written by a developer who has since moved on and this is my first experience working with Subsonic. Note that if event A ends at 2:00 PM and event B starts at 2:00 PM, then events A and B do not constitute a scheduling conflict and the query should reflect that. How would you write this query using Subsonic?
If i'm correct, EventX.Schema.TableName and EventX.Columns.xyz are just constants, and actual variables are startTime, endTime and eventId right?
If so, why not make a stored proc, or at least a parameterized query, so SQL can cache execution plans? IIRC Subsonic supports SPs, but the project site looks like it's about to fall apart.
Sql something like this, could be an SP, or a parameterized query:
SELECT * FROM EventTable
WHERE
(
(
StartTime >= #startTime
AND StartTime < #endTime
)
OR
(
EndTime > #startTime
AND EndTime <= #endTime
)
)
AND
(
EventID <> #eventId
AND
StatusID IN ( 1,2 )
--just made up these numbers, should be the ID of Approved and Completed ...
)
And pass in #startTime, #endTime and #eventId as parameters?
Although I don't know the state of you project, but if I was in your place, probably I would try to leave what's working correctly as it is. And slowly try to replace Subsonic with something actively used in the world, or you are experienced in using it. Would be better both for you, and whoever will have to maintain it later.
Subsonic 3.0 was released about two ago, and feels pretty much dead now. Rob Connery created Massive since, and pretty much abandoned Subsonic if I'm correct...
Edit
Just to make it clear: I'm not saying Subsonic is bad, used and tweaked it's T4 templates a lot to suit my needs. About 2 years ago. But not a lot of people are familiar with it, so moved to other, more widely known data access techniques...

Categories