Entity Framework sqlquery pass current date - c#

I want to call a SQL query with joins to Oracle database. For each table in query i need to check a field for SYSDATE
SELECT
per.PERSON_ID
...
FROM
PERSON_V per
JOIN
SALARY sal ON sal.PERSON_ID = per.PERSON_ID
AND sal.EFF_START_DATE <= SYSDATE
AND sal.EFF_END_DATE > SYSDATE
...
WHERE
per.EFF_START_DATE <= SYSDATE
AND per.EFF_END_DATE > SYSDATE
In my code I do as below
var sql = #"SELECT
per.PERSON_ID
...
FROM PERSON_V per
JOIN SALARY sal
ON sal.PERSON_ID = per.PERSON_ID AND sal.EFF_START_DATE <= GETDATE() AND sal.EFF_END_DATE > GETDATE()
...
WHERE per.EFF_START_DATE <= GETDATE() AND perEFF_END_DATE > GETDATE()";
var oracle_employees = _oracleDbContext.Database.SqlQuery<List<EmployeeDetails>>(sql);
I get GETDATE is invalid identifier. I tried with SYSDATE, DateTime.Now, date as string, none of them worked. What is the right way to pass date to the query from code.

Related

Linq query not working but its equivalent SQL Server query is working

Following SQL query works fine (Give expected results) in SQL Server.
SELECT * FROM ImportedReportDataCRR IRD
INNER JOIN ImportedReport IR ON IRD.ImportedReportId = IR.Id
WHERE
IR.StartDate >= CONVERT(DATETIME, '7/1/2022 12:00:00 AM') AND IR.EndDate <= CONVERT(DATETIME, '7/31/2022 11:59:59 PM')
But when I use equivalent Linq (C# / ASP.Net) its not working as expected (Empty result set returned).
My Linq statement is
var ImportedReportDataList = DbContext.ImportedReportDataCRRs.Where(w =>
(w.ImportedReport.StartDate.Value >= StartDate && w.ImportedReport.EndDate.Value <= EndDate)).ToList();
-- Update Starts --
Linq converts into following SQL query
exec sp_executesql N'SELECT
[Extent1].*
FROM
[dbo].[ImportedReportDataCRR] AS [Extent1]
INNER JOIN [dbo].[ImportedReport] AS [Extent2] ON [Extent1].[ImportedReportId] = [Extent2].[Id]
WHERE
([Extent2].[StartDate] >= #p__linq__0) AND
([Extent2].[EndDate] <= #p__linq__1)',N'#p__linq__0 datetime2(7),#p__linq__1 datetime2(7)',#p__linq__0='2022-07-01 00:00:00.0010000',#p__linq__1='2022-07-31 23:59:59.9970000'
i.e. Linq is converting StartDate and EndDate into datetime2(7) which is creating issue.
-- Update Ends --
Variable StartDate = 7/1/2022 12:00:01 AM
Variable EndDate = 7/31/2022 11:59:59 PM
ImportedReport.StartDate = 2022-07-01 00:00:00.000 (DB field value)
ImportedReport.EndDate = 2022-07-31 00:00:00.000 (DB field value)
As mentioned in the comments, don't try to simulate BETWEEN where you find the end of a date range. This is problematic because different data types consider the "end" of a period differently. In this case, much better to say "greater than or equal to the first of July, and less than the first of August." Also using non-regional and unambiguous date formats:
SELECT <cols>
FROM dbo.ImportedReportData AS IRD
INNER JOIN dbo.ImportedReport AS IR ON IRD.ImportedReportId = IR.Id
WHERE IR.StartDate >= '20220701'
AND IR.EndDate < '20220801'
AND IRD.EmployeeName = 'test';
Please read all of the links at Dating Responsibly.
I suppose in Linq you could say:
&& w.ImportedReport.EndDate.Value
< { whatever you do in Linq to add a day to EndDate }

How query Db with datetimeoff using entityframework

I want to query the database with a column with datetimeoffset(7). This takes startDate and endDate as seen in the code below.
my URL is something like this
http://localhost:60018/v1/getDepartPoints?startDate=2015-08-08&endDate=2015-08-08
Below is my query that returned 0 list
var result = Db.Points.Where(t => t.DepartureTime > startDate && t.DepartureTime < endDate).ToList();
Below is the sql query that works
SELECT * FROM [dbo].[Points] WHERE DepartureTime = '2015-08-08 04:35:00.0000000 -10:00'
This below query didnt work as I expected after casting to datetime
SELECT * FROM [dbo].[Points] WHERE cast(DepartureTime as datetime) = '2015-08-08'
How can I make my query return the expected list with the datetime passed to datetimeoffset in the Database?

Select records for two tables where any parameter can be empty

I am using SQL Server 2008, and development in C#. I just started it a week. and stuck with this scenario. I have two tables
Table 1:
EMID EMNA EMCN
---------------------------
1 Junaid 1347609
2 Jhon 1347610
3 Shwan 1347611
4 ABC 1347612
Table 2:
EMCN ALDT ALTM
--------------------------------
1347609 12/21/2015 52:00.0
1347609 12/21/2015 30:00.0
1347610 12/21/2015 50:00.0
1347610 12/22/2015 30:00.0
1347611 12/23/2015 50:00.0
1347611 12/21/2015 43:00.0
1347609 12/30/2015 25:00.0
1347611 12/29/2015 13:00.0
1347611 12/28/2015 43:00.0
1347609 12/27/2015 24:00.0
1347610 12/26/2015 03:00.0
Required output:
EMNA ALDT ALTM
-------------------------
Junaid 30-Dec-2015 16:25
Jhon 29-Dec-2015 20:13
Shawn 28-Dec-2015 06:43
Junaid 27-Dec-2015 15:24
Jhon 26-Dec-2015 10:03
Shawn 23-Dec-2015 11:50
Jhon 22-Dec-2015 13:30
Junaid 21-Dec-2015 09:30
Jhon 21-Dec-2015 18:50
Junaid 21-Dec-2015 14:52
Shawn 21-Dec-2015 09:43
User can select multiple employees and date range and any field can be null, in SQL Server this query return results, but in C# I am not able to get the results. The problem is with IN(), if no user is selected i.e EMID is blank it should return all records for selected date range. If one date is select it should return result for that date only
SQL query
Declare #EMID int;
Declare #FromDate date;
Declare #ToDate date;
if #FromDate is null
SET #FromDate = #ToDate;
if #ToDate is null
SET #ToDate = #FromDate;
Select
E.EMNA,
REPLACE(LEFT(CONVERT (varchar, c.ALDT, 106),11),' ','-') AS ALDT,
CONVERT(VARCHAR(5),c.ALTM , 108) AS ALTM
from
Table1 E
join
Table2 C on E.EMCN = C.EMCN
where
(E.EMID IN(#EMID) OR #EMID IS NULL)
and (c.ALDT > #FromDate OR #FromDate IS NULL)
and (c.ALDT < dateadd(day,1,#ToDate) OR #ToDate IS NULL)
order by
C.ALDT DESC
SQL string
string strSqlQuery = string.Format(#"
Declare #EMID int;
Declare #FromDate date;
Declare #ToDate date;
SET #EMID = {0};
SET #FromDate = '{1}';
if #FromDate is null
SET #FromDate = #ToDate;
SET #ToDate = '{2}';
if #ToDate is null
SET #ToDate = #FromDate;
Select
E.EMNA,
REPLACE(LEFT(CONVERT (varchar, c.ALDT, 106),11),' ','-') AS ALDT,
CONVERT(VARCHAR(5),c.ALTM , 108) AS ALTM
from
A01001 E
join
A01008 C on E.EMCN = C.EMCN
where
(E.EMID IN(#EMID) OR #EMID IS NULL)
and (c.ALDT > #FromDate OR #FromDate IS NULL)
and (c.ALDT < dateadd(day, 1, #ToDate) OR #ToDate IS NULL)
order by
Y C.ALDT DESC",
objCabinet.strEmployeeId, strFromDate,objCabinet.strToDate);
How can I fix this query or my string to get it working for following scenario
multiple employees are selected but not date range
multiple employees are selected with date range
multiple employee are selected with one date
I created a stored procedure but its not returning values .
Stored procedure:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[sptEmpCabAccess]
#EMID int = null,
#FromDate date = null,
#ToDate date = null
AS
BEGIN
IF (#FromDate IS NULL)
SET #FromDate = #ToDate;
IF (#ToDate IS NULL)
SET #ToDate = #FromDate;
Select
E.EMNA,
REPLACE(LEFT(CONVERT (varchar, c.ALDT, 106),11),' ','-') AS ALDT,
CONVERT(VARCHAR(5),c.ALTM , 108) AS ALTM
from
A01001 AS E
join
A01008 AS C on E.EMCN = C.EMCN
where
(E.EMID IN(#EMID) OR #EMID IS NULL)
and (c.ALDT > #FromDate OR #FromDate IS NULL)
and (c.ALDT < dateadd(day,1,#ToDate) OR #ToDate IS NULL)
order by
C.ALDT DESC
END
GO
C# code calling the stored procedure:
using (SqlConnection objsqlconn = new SqlConnection(conn))
{
objsqlconn.Open();
try
{
using (SqlCommand objcmd = new SqlCommand("sptEmpCabAccess", objsqlconn))
{
objcmd.CommandType = CommandType.StoredProcedure;
objcmd.Parameters.Add("#EMID", SqlDbType.Int).Value = objCabinet.strEmployeeId;
objcmd.Parameters.Add("#FromDate", SqlDbType.Date).Value = objCabinet.strFromDate; ;
objcmd.Parameters.Add("#ToDate", SqlDbType.Date).Value = objCabinet.strToDate;
// error here cannot implicitly convert type 'int' to 'system.data.dataset'
dsGetData = objcmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
throw ex;
}
}
You need to change query where you are applying filters, in place of checking with Null assign some default values like
1) Declare #EMID int=0;
2) WHERE (E.EMID IN(#EMID) OR #EMID=0)

Stored procedure with nullable value in date field

In this stored procedure , in a where condition if #startDate and #EndDate values are null then how it can be handle using COALESCE.
CREATE PROCEDURE dbo.SP_ManageLeaveSearch
#StartDate datetime,
#EndDate datetime,
#UserName CHAR(100),
#MarketID INT
AS
BEGIN
SELECT d1.UserName,c1.HouseName,c.StartDate,c.EndDate
FROM table1 c
Inner JOIN table2 d1 ON c.UserID = d1.UserID
WHERE
(
(
(#StartDate BETWEEN StartDate AND EndDate)
OR
(#EndDate BETWEEN StartDate AND EndDate)
OR
(
(#StartDate <= Startdate AND #EndDate>=EndDate)
)
)
AND
(
d1.UserName = COALESCE(#UserName, d1.UserName)
)
)
END
Thnaks in advance.
This should work for you:
CREATE PROCEDURE dbo.ManageLeaveSearch
#StartDate datetime = NULL,
#EndDate datetime = NULL,
#UserName CHAR(100) = NULL,
#MarketID INT
AS
BEGIN
SELECT d1.UserName,c1.HouseName,c.StartDate,c.EndDate
FROM table1 c
Inner JOIN table2 d1 ON c.UserID = d1.UserID
WHERE
COALESCE(#StartDate,StartDate) <= EndDate AND
StartDate <= COALESCE(#EndDate,EndDate) AND
d1.UserName = COALESCE(#UserName, d1.UserName)
END
Notes:
Don't name stored procedures with an sp_ prefix - it's reserved for Microsoft's system procedures.
I've gone with simpler conditions for determining an overlap exists. An overlap exists between two ranges if range 1 starts before range 2 ends, and range 2 starts before range 1 ends.
I've specified defaults for those parameters that should be nullable.
Try this one -
CREATE PROCEDURE dbo.usp_ManageLeaveSearch
#StartDate DATETIME,
#EndDate DATETIME,
#UserName CHAR(100),
#MarketID INT
AS BEGIN
SELECT
d1.UserName
, c.HouseName
, c.StartDate
, c.EndDate
FROM dbo.table1 c
JOIN dbo.table2 d1 ON c.UserID = d1.UserID
WHERE d1.UserName = ISNULL(#UserName, d1.UserName)
AND (
ISNULL(#StartDate, StartDate) BETWEEN StartDate AND EndDate
OR
ISNULL(#EndDate, EndDate) BETWEEN StartDate AND EndDate
)
END
You've overly complicated things. This should work for you, and is as simple of a query as I know of. I prefer this syntax because in most of my use cases, the ...OR #UserName IS NULL can be removed from the query before it is even executed thereby making a very simple, fast execution.
CREATE PROCEDURE dbo.SP_ManageLeaveSearch
#StartDate datetime,
#EndDate datetime,
#UserName CHAR(100),
#MarketID INT
AS
BEGIN
SELECT d1.UserName,c1.HouseName,c.StartDate,c.EndDate
FROM table1 c
JOIN table2 d1
ON c.UserID = d1.UserID
WHERE (#StartDate<=EndDate OR #StartDate IS NULL)
AND (#EndDate>=StartDate OR #EndDate IS NULL)
AND (d1.UserName = #UserName OR #UserName IS NULL)
END

MS Access query code in C#

I'm trying to run a query on an Access DB, I'm used to SQL queries but this doesn't seem to be working the same way. Here's my query:
OleDbCommand command = new OleDbCommand();
command.Connection = connect;
command.CommandText = "SELECT RecordID, TimeStamp, EmployeeName, AreaDescription FROM LoginRecords r, Employees e, Areas a WHERE((e.EmployeeID = r.EmployeeID) && (a.AreaID =r.AreaID) && (TimeStamp > startDate AND < endDate)) ORDER BY TimeStamp;"
I can't seem to get this to run but technically from a SQL standpoint this should be a good query. The tables are LoginRecords, Employees, Areas. I can load the tables if that would be helpful. I appreciate any feedback as to why this won't work in Access. And startDate and endDate are variables from user input boxes.
Try this one,
This is SQL-92
SELECT RecordID,
TimeStamp,
EmployeeName,
AreaDescription
FROM LoginRecords r
INNER JOIN Employees e
ON e.EmployeeID = r.EmployeeID
INNER JOIN Areas a
ON a.AreaID = r.AreaID
WHERE TimeStamp > startDate AND
TimeStamp < endDate
ORDER BY TimeStamp;
Use SQL-92 format rather SQL-89 format because SQL-89 (aside from old style) is prone to going CROSS JOIN if not handled correctly.
and this is SQL-89
SELECT RecordID,
TimeStamp,
EmployeeName,
AreaDescription
FROM LoginRecords r, Employees e, Areas a
WHERE (e.EmployeeID = r.EmployeeID) AND
(a.AreaID = r.AreaID) AND
(TimeStamp > #startDate AND
TimeStamp < #endDate)
ORDER BY TimeStamp;
MSACCESS: INNER JOIN, OUTER JOIN (LEFT and RIGHT)

Categories

Resources