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
Related
How can I convert this inline SQL to a stored procedure
SELECT
PM.ProjectName
,[PurposeorReason]
,Reg.Name
,EA.Comment as Comment
,[FromDate]
,[VoucherID]
,[TotalAmount]
,ex.CreatedOn
FROM [TimesheetDB].[dbo].[Expense] ex
inner join Registration Reg on reg.RegistrationID = ex.UserID
inner join ProjectMaster PM on ex.ProjectID =PM.ProjectID
inner join AssignedRoles AR on reg.RegistrationID = AR.RegistrationID
inner join ExpenseAuditTB EA on ex.ExpenseID = EA.ExpenseID
where FromDate between '2019-09-25' and '2019-09-29'
and ea.ProjectID IN (1,2,5)
and EA.Status = 2
I have issues with the (1,2,5) part. I have it in C# as a string "1,2,5" and the ProjectID is integer.
I know I am doing something wrong. The query itself works well.
I suggest a table-valued parameter to pass lists/arrays to a stored procedure. In the C# code, specify parameter type SqlDbType.Structured as the parameter type. The parameter value can be a DataTable, IEnumerable<SqlDataRecord>, or DbDataReader. I suggest a DataTable with a single column for this use case.
CREATE TYPE dbo.TVPProjectIdList AS TABLE (
ProjectId int NOT NULL PRIMARY KEY
);
GO
CREATE PROCEDURE dbo.Example
#StartDate date
, #EndDate date
, #Status int
, #ProjectIdList dbo.TVPProjectIdList READONLY
AS
SET NOCOUNT ON;
SELECT
PM.ProjectName
,[PurposeorReason]
,Reg.Name
,EA.Comment as Comment
,[FromDate]
,[VoucherID]
,[TotalAmount]
,ex.CreatedOn
FROM [TimesheetDB].[dbo].[Expense] ex
inner join Registration Reg on reg.RegistrationID = ex.UserID
inner join ProjectMaster PM on ex.ProjectID =PM.ProjectID
inner join AssignedRoles AR on reg.RegistrationID = AR.RegistrationID
inner join ExpenseAuditTB EA on ex.ExpenseID = EA.ExpenseID
where FromDate between #StartDate and #EndDate
and ea.ProjectID IN (SELECT ProjectId FROM #ProjectIdList)
and EA.Status = #Status;
GO
You have to add commas at the beginning and at the end of #ProjectId string.
In c# How to Get comma value at the beginning and at the end
string str = "1,2,5";
string replaced=str.Replace(',',',');
string concatenatdvalue=","+replaced+',';
Result = ",1,2,5,"
Then result value you can Pass as #ProjectId into SQL Server......
CREATE PROCEDURE dbo.sp_ProjectReport
(
#FromDate VARCHAR(20)=NULL,
#ToDate VARCHAR(20)=NULL,
#ProjectId VARCHAR(50)=NULL,
#StatusId INT=NULL
)
AS
BEGIN
SELECT
PM.ProjectName
,[PurposeorReason]
,Reg.Name
,EA.Comment as Comment
,[FromDate]
,[VoucherID]
,[TotalAmount]
,ex.CreatedOn
FROM [TimesheetDB].[dbo].[Expense] ex
inner join Registration Reg on reg.RegistrationID = ex.UserID
inner join ProjectMaster PM on ex.ProjectID =PM.ProjectID
inner join AssignedRoles AR on reg.RegistrationID = AR.RegistrationID
inner join ExpenseAuditTB EA on ex.ExpenseID = EA.ExpenseID
where
convert(DATETIME,FromDate) BETWEEN Convert(DATETIME,CASE WHEN isnull(#FromDate,'')='' THEN FromDate ELSE isnull(#FromDate,'') END)
AND Convert(DATETIME, CASE WHEN isnull(#ToDate,'')='' THEN FromDate ELSE isnull(#ToDate,'') END)
and CHARINDEX(','+cast(ea.ProjectID as varchar(100))+',', #ProjectId) > 0
and EA.Status = #StatusId
END
Testing Script For Executing SP
EXEC dbo.sp_ProjectReport
#FromDate='2019-09-25',
#ToDate='2019-09-29',
#ProjectId=',1,2,5,',
#StatusId='2'
Note:- Here i'm changing also logic of FromDate to ToDate
.........null part is also Handle in Custom Date Range.......
For E.g.
If you are enter only FromDate as "07/06/2017" then it will give you
from result("07/06/2017" to last Date)
I execute a stored procedure as follows:
exec SALESREPORTFORWEB
#StartDate = '03/20/2017', #EndDate = '03/21/2017'
Stored Procedure
CREATE proc [dbo].[SALESREPORTFORWEB]
--SALESREPORTFORWEB #StartDate='03-20-2017' ,#EndDate='03-28-2017',#usercode in ('2739','1609')
#StartDate DATETIME =NULL ,
#EndDate DATETIME =NULL ,
#ITEMCODE VARCHAR(100)=NULL,
#ITEMDESCRIPTION VARCHAR(100)=NULL,
#CLIENTCODE Varchar(25) = null,
#CLIENTNAME VARCHAR(100)=NULL,
#CLIENTBRANCHCODE VARCHAR(100)=NULL,
#CLIENTBRANCHNAME VARCHAR(100)=NULL,
#BRANDCODE VARCHAR (25)=NULL,
#BRANDNAME VARCHAR(100)=NULL,
#USERCODE VARCHAR(25)=NULL,
#USERNAME VARCHAR(100)=NULL,
#SUBCHANNEL VARCHAR(25)=NULL
AS
SELECT H.UserCode,U.SALESMANNAME, CONVERT(CHAR(10), H.TrxDate, 103) AS DATE,D.ItemCode,I.Description AS ITEMDESCRIPTION,d.ItemGroupLevel5 AS BRANDCODE,
B.Description AS BRANDNAME,
H.ClientCode,
C1.Description AS Client,H.ClientBranchCode,C2.Description, C2.SubChannelCode AS BRANCHSUBCHANNEL,
ROUND(
SUM(
CASE WHEN D.QuantityLevel1 > 0 THEN
D.QuantityLevel1 * PriceUsedLevel1
ELSE
D.QuantityLevel3 * PriceUsedLevel3
END - ISNULL(D.TotalDiscountAmount, 0)
), 2) AS TrxAmount,SUM(D.QuantityBU) AS QTY
FROM tblTrxHeader H INNER JOIN
tblTrxDetail D ON H.TrxCode = D.TrxCode AND D.TrxStatus > 0 INNER JOIN
tblBrand B ON B.Code=D.ITEMGROUPLEVEL5 INNER JOIN
tblClient C1 ON H.ClientCode = C1.Code
INNER JOIN tblClient C2 ON H.ClientBranchCode=C2.Code
INNER JOIN TBLITEM I ON I.ITEMCODE=D.ITEMCODE
/*LEFT OUTER JOIN
tblRegion R ON R.Code = C.RegionCode*/ LEFT OUTER JOIN
vw_UnitManagers U ON U.SalesmanCode = H.UserCode
WHERE
H.TrxType IN (1) AND
DATEDIFF(dd,H.TrxDate,ISNULL(#StartDate,GETDATE())) <= 0 AND DATEDIFF(dd,H.TrxDate,ISNULL(#EndDate,GETDATE())) >= 0 AND
D.ITEMCODE= ISNULL(#ITEMCODE,D.ITEMCODE) AND
H.CLIENTCODE= ISNULL(#CLIENTCODE,H.CLIENTCODE)AND
H.ClientBranchCode=ISNULL(#CLIENTBRANCHCODE,H.ClientBranchCode) AND
D.ItemGroupLevel5=ISNULL(#BRANDCODE,D.ItemGroupLevel5)AND
H.UserCode in (ISNULL(#USERCODE,H.UserCode)) AND
C2.SubChannelCode=ISNULL(#SUBCHANNEL,C2.SubChannelCode)AND
B.Description LIKE('%'+ISNULL(#BRANDNAME,B.Description)+'%')AND
I.Description LIKE('%'+ISNULL(#ITEMDESCRIPTION,I.Description)+'%')AND
C1.Description LIKE('%'+ISNULL(#CLIENTNAME,C1.Description)+'%')AND
C2.Description LIKE('%'+ISNULL(#CLIENTBRANCHNAME,C2.Description)+'%')AND
U.SalesmanName LIKE('%'+ISNULL(#USERNAME,U.SalesmanName)+'%')
GROUP BY
--CONVERT(VARCHAR, H.TrxDate, 101),
H.UserCode,U.SALESMANNAME,H.TRXDATE,D.itemcode,I.Description,d.ItemGroupLevel5,
B.Description, H.ClientCode,C1.Description,H.ClientBranchCode,C2.Description, C2.SubChannelCode
ORDER BY H.TrxDate
where #StartDate = '03/20/2017' and #EndDate = '03/21/2017' are the parameters of the stored procedure.
In my code this is how it looks:
var salesDataQuery = SalesDataModel.FromSql("exec SALESREPORTFORWEB '#StartDate='#StartDate, '#EndData='#EndData",
new SqlParameter("#StartDate", startdate),
new SqlParameter("#EndData", enddate));
But this code throws an error:
Invalid syntax error near '#StartDate='
Can somebody help me make the right stored procedure call?
Many thanks!
How about cropping parameters form exec like that:
var salesDataQuery = SalesDataModel.FromSql("exec SALESREPORTFORWEB #StartDate, #EndDate",
new SqlParameter("#StartDate", startdate),
new SqlParameter("#EndData", enddate));
Edit: added parameters to procedure.
I mostly update my data model by deleting my .EDMX file and adding it again, just to make sure I get everything I have in the database.
I ran into a strange issue, where one of my stored procedure return types has been changed after deleting and re-adding the .EDMX. The stored procedure code remains unchanged, and can be found below. I am not sure what wrong I did?
SQL Server stored procedure (never changed):
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[usp_SearchOrders]
#orderid int = null, #statusid int = null,
#startdate datetime = null, #enddate datetime = null,
#customername varchar(30) = null, #customeraddress varchar(30) = null
AS
SELECT
O.OrderID Order_ID, O.OrderDate,
OrderTotal = (SELECT SUM(od.UnitPrice - (od.UnitPrice * od.Discount))
FROM [Order Details] od
WHERE od.OrderID = O.OrderID),
Discount = (SELECT SUM(od.UnitPrice * od.Discount)
FROM [Order Details] od
WHERE od.OrderID = O.OrderID),
CC.Email1, CC.Phone,
Status = (SELECT OS.OrderStatusName
FROM OrderStatus OS
WHERE OS.OrderStatusID = O.OrderStatusID),
OrderType = (SELECT OT.OrderTypeName
FROM OrderType OT
WHERE OT.OrderTypeID = O.OrderTypeID)
FROM
Orders O
JOIN
Customers C ON O.CustomerID = C.CustomerID
JOIN
CustomersContactDetails CC ON C.CustomerID = CC.CustomerID
WHERE
(O.OrderID = #orderid OR #orderid IS NULL)
AND (O.OrderStatusID = #statusid OR #statusid IS NULL)
AND (O.OrderDate >= #startdate OR #startdate IS NULL)
AND (O.OrderDate <= #enddate OR #enddate IS NULL)
AND (C.CustomerName LIKE #customername OR #customername IS NULL)
AND (CC.Address LIKE #customeraddress OR #customeraddress IS NULL)
AND (CC.City LIKE #customeraddress OR #customeraddress IS NULL)
C# code: _dbContext.usp_SearchOrders(1,1,DateTime.Now, DateTime.Now.AddDays(1),'Hitin','BH');
Before update return type: usp_SearchOrders_Result
After re-adding return type: int
I never made any complex type or did any mapping, the class usp_SearchOrders_Result was created on it own.
What could be the possible reason behind this issue?
You need to have "SET NOCOUNT ON" at the top of your stored procedure.
I have the following query
DECLARE #StartDate DATETIME, #EndDate DATETIME
SET #StartDate = DATEADD(mm,-1, getdate())
select count(status) from [full]
where (date_reception> #StartDate and status = 'OPEN')
I need to get result of one month before now , for example we are in 2015-03-19 i need to get result from 2015-02-19 till now.
When i try query above i get as result (4412) and when i try (where date_reception >'2015-02-19') i get (5638)
If the time component of the date is not to be considered, try the following code. If it is, your current code seems accurate.
DECLARE #StartDate DATETIME, #EndDate DATETIME, #currentDate date
set #currentDate = GETDATE()
SET #StartDate = DATEADD(mm,-1, #currentDate))
select count(status) from [full]
where (date_reception> #StartDate and status = 'OPEN')
try
WHERE date_reception BETWEEN DATEADD(month, -1, GETDATE()) AND DATEADD(GETDATE())
Any idea when i pass the type to the stored proecedure the dates are being ignored
ALTER PROCEDURE [dbo].[hms_GetBenefitsByDateType]
(
#id int,
#startDate datetime,
#EndDate datetime,
#bType int
)
AS
SET NOCOUNT ON;
SELECT benefit.emp_no, benefit.record_id, benefit.contract_id, benefit.career_id, benefit.date_from, benefit.date_to, benefit.benefit_type, benefit.monthly_value, benefit.benefit_provider, benefit.level_of_cover, benefit.current_benefit, benefit.previous_monthly_cost, benefit.benefit_change_details, benefit.notes, benefit.level_description, benefit.monthly_annual, benefit.cover_level, benefit.qualifying_reason, benefit_type.desc_
FROM benefit INNER JOIN
benefit_type ON benefit.benefit_type = benefit_type.code
WHERE (benefit.benefit_type = #bType) or (benefit.emp_no = #id) and (benefit.date_from >= #startDate) and (benefit.date_to <= #EndDate)
where date from is 2006-01-01 00:00:00.000 and date to is 1900-01-01 00:00:00.000
The result being produced is the following
11,4,21,123,2006-01-01 00:00:00.000,1900-01-01 00:00:00.000,3,15.00,1,2.00,1,0.00,None ,Notes ,Children ,1,1,1,Medical Cover - Children
12,6,14,27,2013-06-21 00:00:00.000,2013-06-21 00:00:00.000,3,500.00,0,0.00,1,0.00,
i would go for where like this one
WHERE (benefit.benefit_type = #bType) or (benefit.emp_no = #id) and ( (benefit.date_from >= #startDate) and (benefit.date_to <= (#EndDate + 1)) )
#UPDATE 1
WHERE (benefit.benefit_type = #bType) or (benefit.emp_no = #id) and ( (benefit.date_from IS NULL or benefit.date_from >= #startDate) and ( benefit.date_to IS NULL or benefit.date_to <= (#EndDate + 1)) )
I also think your problem lies in the where condition. I think you should add more parenthesis to make the condition more clear. For ex you can try the following (Hoping I got it right)
WHERE ((benefit.benefit_type = #bType) OR (benefit.emp_no = #id)) and
((benefit.date_from >= #startDate) and (benefit.benefit_type <= #EndDate))