Not able to search the data in stored procedure - sql

I need to search by Suburb however it does not return anything even though there's a data. Here is the stored procedure implementation and I have added it in the where statement. Please help me what cause the issue. Thank you.
WHERE
((#DriverId = '00000000-0000-0000-0000-000000000000') OR
(#DriverId IS NULL AND tl.T_DriverId IS NULL) OR
(#DriverId IS NOT NULL AND tl.T_DriverId = #DriverId)) AND
((#SearchBySuburb IS NOT NULL AND #Suburb = 0 AND pa.A_Suburb = #SearchBySuburb) AND
(#SearchBySuburb IS NOT NULL AND #Suburb = 1 AND da.A_Suburb = #SearchBySuburb)) AND
((#HideCompleted = 1 AND #StatusId = 0 AND tl.T_Status != 8) OR
(#HideCompleted = 1 AND #StatusId = 0 AND tl.T_Status IS NULL) OR
(#HideCompleted = 1 AND #StatusId > 0 AND tl.T_Status = #StatusId) OR
(#HideCompleted = 0 AND #StatusId = 0) OR
(#HideCompleted = 0 AND #StatusId > 0 AND tl.T_Status = #StatusId)) AND
(#OrganizationId IS NULL OR o.O_ID = #OrganizationId) AND
((#StartDate IS NULL AND tl.T_PlannedDeliveryDate IS NULL) OR (#EndDate IS NULL AND tl.T_PlannedDeliveryDate IS NULL) OR (tl.T_PlannedDeliveryDate BETWEEN CAST(#StartDate AS DATE) AND CAST(#EndDate AS DATE)))

The only time you use #SearchBySuburb is in the following fragment
((#SearchBySuburb IS NOT NULL AND #Suburb = 0 AND pa.A_Suburb = #SearchBySuburb) AND
(#SearchBySuburb IS NOT NULL AND #Suburb = 1 AND da.A_Suburb = #SearchBySuburb))
Given they're all AND, that part cannot ever evaluate as true because you're checking if #Suburb = 0 AND #Suburb = 1.
I suggest being very explicit with brackets and checking your ANDs and ORs.
Update following OP's comment about it still not working
I've re-formatted your WHERE into conceptual groups separated by AND clauses- see below. The groups are broadly about the driver, suburb, status, organisation, and start/end dates.
My suggestion is to
a) Start with none of them (which should therefore show all rows)
b) Add the groups (separated by ANDs) to the WHERE clause one at a time until your desired rows disappear
When your desired rows disappear, it tells you there's a problem with the last added filters to the WHERE clause.
WHERE
(
(#DriverId = '00000000-0000-0000-0000-000000000000')
OR (#DriverId IS NULL AND tl.T_DriverId IS NULL)
OR (#DriverId IS NOT NULL AND tl.T_DriverId = #DriverId)
)
AND
(
(#SearchBySuburb IS NOT NULL AND #Suburb = 0 AND pa.A_Suburb = #SearchBySuburb)
OR (#SearchBySuburb IS NOT NULL AND #Suburb = 1 AND da.A_Suburb = #SearchBySuburb)
)
AND
(
(#HideCompleted = 1 AND #StatusId = 0 AND tl.T_Status != 8)
OR (#HideCompleted = 1 AND #StatusId = 0 AND tl.T_Status IS NULL)
OR (#HideCompleted = 1 AND #StatusId > 0 AND tl.T_Status = #StatusId)
OR (#HideCompleted = 0 AND #StatusId = 0)
OR (#HideCompleted = 0 AND #StatusId > 0 AND tl.T_Status = #StatusId)
)
AND
(#OrganizationId IS NULL OR o.O_ID = #OrganizationId)
AND
(
(#StartDate IS NULL AND tl.T_PlannedDeliveryDate IS NULL)
OR (#EndDate IS NULL AND tl.T_PlannedDeliveryDate IS NULL)
OR (tl.T_PlannedDeliveryDate BETWEEN CAST(#StartDate AS DATE) AND CAST(#EndDate AS DATE))
)

Related

What is purpose of COALESCE = 0

There is some script that I seen where the code is as follows:
AND (PC.SystemID = #SystemID OR COALESCE(#SystemID, 0) = 0)
I understand COALESCE chooses the first not null but not sure what the purpose would be for = 0.
the where clause will return true for the whole AND
When
PC.SystemID = #SystemID
OR #SystemID is NULL
OR #SystemID = 0
so
#SystemID IS NULL OR #SystemID = 0 is equivalent to COALESCE(#SystemID, 0) = 0

Update column by calling function is very slow - how to improve? SQL Server

I need to update some column by calling a function. It takes a too long time.
How can I improve it? What could be the reason it takes so long?
I realized that scalar-function takes more time than a table-function, but I have no idea how to convert this to a table function, is there perhaps another way to do this?
The code that updates:
UPDATE EDBNationalInsuranceMortgageLoad_tmp
SET IsDead = dbo.GetIsDead(IdentityNumber1, #FileId) -- the function
The code of the function:
ALTER FUNCTION [dbo].[GetIsDead]
(#IdentityNumber1 NVARCHAR(9),
#FileId INT)
RETURNS int
AS
BEGIN
DECLARE #mateIdentityNumber NVARCHAR(9);
DECLARE #fullRow1_tmp TABLE
(
IdentityNumber NVARCHAR(9),
MateIdentityNumber NVARCHAR(9),
DeathDate NVARCHAR(8)
);
DECLARE #fullRow2_tmp TABLE
IdentityNumber NVARCHAR(9),
MateIdentityNumber NVARCHAR(9),
DeathDate NVARCHAR(8)
);
DECLARE #countRows2 INT
DECLARE #isDead1 INT = 0
DECLARE #isDead2 INT = 0
SET #mateIdentityNumber = (SELECT TOP 1 MateIdentityNumber
FROM MortgageReturnParticipationBase
WHERE IdentityNumber = #IdentityNumber1
AND MortgageReturnParticipationStatusId = 1)
INSERT INTO #fullRow1_tmp
SELECT TOP 1 IdentityNumber1, IdentityNumber2, DeathDate
FROM EDBNationalInsuranceMortgageLoad_tmp
WHERE IdentityNumber1 = #IdentityNumber1
AND IsRowError = 0
AND FileId = #FileId
SET #isDead1 = (SELECT 1
FROM #fullRow1_tmp
WHERE DeathDate IS NOT NULL)
IF #mateIdentityNumber = 0
BEGIN
IF (#isDead1 = 1)
RETURN 0;
ELSE
RETURN 1;
END
ELSE
BEGIN
INSERT INTO #fullRow2_tmp
SELECT TOP 1 IdentityNumber1, IdentityNumber2, DeathDate
FROM EDBNationalInsuranceMortgageLoad_tmp
WHERE IdentityNumber1 = #mateIdentityNumber
AND IsRowError = 0
AND FileId = #FileId
SET #countRows2 = (SELECT COUNT(*) FROM #fullRow2_tmp)
IF #countRows2 = 0
RETURN 2;
SET #isDead2 = (SELECT 1 FROM #fullRow2_tmp WHERE DeathDate IS NOT NULL)
IF (#isDead1 IS NULL OR #isDead2 IS NULL OR #isDead1 = 0 OR #isDead2 = 0)
RETURN 1;
IF (#isDead1 = 1 AND #isDead2 = 1)
RETURN 0;
END
RETURN NULL;
END
I tried to convert it to a table-function, but it worked slowly:
ALTER FUNCTION dbo.GetIsDeadTableFunc (
#IdentityNumber1 nvarchar(9),
#FileId INT)
RETURNS TABLE AS RETURN
select (case when (b.MateIdentityNumber > 0 and b.MateIdentityNumber
not in (SELECT IdentityNumber1
from EDBNationalInsuranceMortgageLoad_tmp
where IsRowError=0
and FileId=#FileId))
then 2
when (b.MateIdentityNumber = 0
and DeathDate is null)
or (b.MateIdentityNumber > 0 and b.MateIdentityNumber in (SELECT IdentityNumber1
from EDBNationalInsuranceMortgageLoad_tmp
where IsRowError=0
and FileId=#FileId
and (DeathDate is null or DeathDate is not null))
and DeathDate is null)
or (b.MateIdentityNumber > 0 and b.MateIdentityNumber in (SELECT IdentityNumber1
from EDBNationalInsuranceMortgageLoad_tmp
where IsRowError=0
and FileId=#FileId
and DeathDate is null) -- אמור להיות עוד פונה והוא נמצא בקובץ חי
and DeathDate is not null) -- פונה 1 נפטר
then 1
else 0 end) as IsDead
from EDBNationalInsuranceMortgageLoad_tmp e
join MortgageReturnParticipationBase b on b.IdentityNumber = e.IdentityNumber1
WHERE e.IdentityNumber1 = #IdentityNumber1
and IsRowError=0
and FileId=#FileId
and b.MortgageReturnParticipationStatusId=1
GO

IF Else statements in SQL Update Query

I want to write if else in SQL Server Update Query.
UPDATE [dbo].[TempTable]
SET [Level1] = CASE WHEN A = -1 THEN 0 ELSE A END
,[Level2] = CASE WHEN A = -1 THEN 0 ELSE A END;
You need to use CASE in such scenarios. Try the above query..
If you insist on using IF, you can try the following:
IF
IF A = -1 BEGIN
UPDATE [dbo].[TempTable]
SET [Level1] = 0
,[Level2] = 0
END
ELSE BEGIN
UPDATE [dbo].[TempTable]
SET [Level1] = A
,[Level2] = A
END
IIF
UPDATE [dbo].[TempTable]
SET [Level1] = IIF(A = -1, 0, A)
,[Level2] = IIF(A = -1, 0, A)
You can use CASE statement, and If "A" is one of the column in your dbo.TempTable
DECLARE #Table TABLE(A INT,Level1 INT,Level2 INT)
INSERT #Table
SELECT -1, NULL, NULL UNION ALL
SELECT 1,NULL,NULL
UPDATE t SET
Level1 = CASE WHEN A = -1 THEN 0 ELSE A END,
Level2 = CASE WHEN A = -1 THEN 0 ELSE A END
FROM #Table t
SELECT * FROM #Table
-- Result
A Level1 Level2
-1 0 0
1 1 1
With case or IIF ;)
UPDATE [dbo].[TempTable]
SET [Level1] = IIF(A = -1 , 0 , A), [Level2] = IIF(A = -1 , 0 , A)
This will work:
UPDATE [dbo].[TempTable]
SET [Level1] = IIF(A = -1, 0, A), [Level2] = IIF(A = -1, 0, A);

Invalid column error in SQL Server 2008

I am trying to run the following query,
DECLARE #p_UserName as nvarchar(100)
DECLARE #p_Department as int
DECLARE #p_Section as int
DECLARE #p_SubSection as int
DECLARE #p_PermissionGroup as int
DECLARE #p_DistributionGroup as int
DECLARE #p_Permission as nvarchar(100)
DECLARE #p_IfPerChecked as bit
DECLARE #p_Role as int
SET #p_UserName = ''
SET #p_Department = NULL
SET #p_Section = NULL
SET #p_SubSection = NULL
SET #p_PermissionGroup = NULL
SET #p_DistributionGroup = NULL
SET #p_Permission = ''
SET #p_Role = NULL
SELECT Users.EnglishName,
(SELECT Designation.TitleEnglish FROM Designation WHERE Users.Designation = Designation.ID) AS [Role],
(SELECT Department.TitleEnglish FROM Department WHERE Users.DepartmentID = Department.ID) AS [Department],
(SELECT Section.TitleEnglish FROM Section WHERE Users.SectionID = Section.SectionID) AS [Section],
(SELECT SubSection.TitleEnglish FROM SubSection WHERE Users.SubSectionID = SubSection.SubSectionID) AS [Sub-Section],
(SELECT Groups.TitleEnglish FROM Groups WHERE
(SELECT UserRights.GroupID FROM UserRights WHERE Users.UserID = UserRights.UserID) = Groups.GroupID
AND Groups.IsDistribution = 0
) AS [Permissions Group],
(SELECT Groups.TitleEnglish FROM Groups WHERE
(SELECT UserRights.GroupID FROM UserRights WHERE Users.UserID = UserRights.UserID) = Groups.GroupID
AND Groups.IsDistribution = 1
) AS [Distribution Group],
(CASE
WHEN Users.ApplyUserRights = 1 THEN dbo.fn_GetUserPermissions('Users', Users.UserID)
WHEN Users.ApplyUserRights = 0 THEN dbo.fn_GetUserPermissions('Groups', (SELECT GroupID FROM UserRights WHERE Users.UserID = UserRights.UserID))
END) AS [Permissions]
FROM Users WHERE
((#p_UserName <> NULL OR #p_UserName <> '') AND #p_UserName = Users.UserName) OR
((#p_Department <> NULL OR #p_Department <> 0) AND #p_Department = Users.DepartmentID) OR
((#p_Section <> NULL OR #p_Section <> 0) AND #p_Section = Users.SectionID) OR
((#p_SubSection <> NULL OR #p_SubSection <> 0) AND #p_SubSection = Users.SubSectionID) OR
((#p_PermissionGroup <> NULL OR #p_PermissionGroup <> 0) AND #p_PermissionGroup = (
SELECT Groups.GroupID FROM Groups WHERE
(SELECT UserRights.GroupID FROM UserRights WHERE Users.UserID = UserRights.UserID) = Groups.GroupID
AND Groups.IsDistribution = 0
)) OR
((#p_DistributionGroup <> NULL OR #p_DistributionGroup <> 0) AND #p_DistributionGroup = (
SELECT Groups.GroupID FROM Groups WHERE
(SELECT UserRights.GroupID FROM UserRights WHERE Users.UserID = UserRights.UserID) = Groups.GroupID
AND Groups.IsDistribution = 1
)) OR
(1 = CASE
WHEN Users.ApplyUserRights = 1 AND #p_Permission = 'AllowChangePassword' THEN 0
ELSE dbo.fn_CheckPemission(#p_Permission, UserID)
END) OR
((#p_Role <> NULL OR #p_Role <> 0) AND #p_Role = Users.Designation) OR
(1 = 1)
GROUP BY CASE #GroupBy
WHEN 'DepartmentID' THEN Users.DepartmentID
WHEN 'SectionID' THEN Users.SectionID
WHEN 'SubSectionID' THEN Users.SubSectionID
ELSE Users.EnglishName
END
And I keep getting the error
Column 'Users.EnglishName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Please help!
Like the message states, you need to group by the EnglishName column unless it is used in an aggregate function(Max or sum or likewise).
The issue is evident from your error message. Use GROUP BY in case of aggregate functions.

SQL geting Top X number of rows

i want to get only the top x number of the query. where the x will be send by parameter how can i do this?
I know i can take it as string and exec it later but i find it very cumbersome.
This the query i have and #ArticleNo is the parameter i want to take as x.
Create proc [dbo].[GW2_Report_SlowFastMovingArticle]
#ArtKey bigint = null,
#ArtCatKey int= null,
#ArtGroupKey int= null,
#ArtTypeKey int= null,
#MaterialKey int= null,
#ColorKey int= null,
#VendorTypeKey int = null,
#VendorKey bigint = null,
#FromDate datetime = null,
#ToDate datetime = null,
#MovingType int = 0,
#PerformanceType int = 0,
#ArticleNo int = 10,
#OutletKey int = null
AS
BEGIN
SELECT
dbo.Sal_POSDet.ArtKey,
dbo.ArtWithVendor.ArtCode,
dbo.ArtWithVendor.ArtName,
Sum(isnull(dbo.Sal_POSDet.Qty,0))as Pair,
Sum(isnull(dbo.Sal_POSDet.Total,0)) as TurnOver
into #temp FROM
dbo.Sal_POS INNER JOIN
dbo.Sal_POSDet ON
dbo.Sal_POS.SalesKey = dbo.Sal_POSDet.SalesKey INNER JOIN
dbo.ArtWithVendor ON
dbo.Sal_POSDet.ArtKey = dbo.ArtWithVendor.ArtKey
WHERE
Sal_POS.IsHold=0 and
Sal_POS.SalesDate between #FromDate and #ToDate and
CASE WHEN #ArtKey is null THEN 1 WHEN ArtWithVendor.ArtKey =#ArtKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtCatKey is null THEN 1 WHEN ArtWithVendor.ArtCatKey =#ArtCatKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtGroupKey is null THEN 1 WHEN ArtWithVendor.ArtGroupKey = #ArtGroupKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtTypeKey is null THEN 1 WHEN ArtWithVendor.ArtTypeKey = #ArtTypeKey THEN 1 ELSE 0 END = 1
and CASE WHEN #MaterialKey is null THEN 1 WHEN ArtWithVendor.MaterialKey = #MaterialKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ColorKey is null THEN 1 WHEN ArtWithVendor.ColorKey = #ColorKey THEN 1 ELSE 0 END = 1
and CASE WHEN #VendorKey is null THEN 1 WHEN ArtWithVendor.VendorKey = #VendorKey THEN 1 ELSE 0 END = 1
and CASE WHEN #VendorTypeKey is null THEN 1 WHEN ArtWithVendor.VendorTypeKey = #VendorTypeKey THEN 1 ELSE 0 END = 1
and CASE WHEN #OutLetKey is null THEN 1 WHEN Sal_POS.OutLetKey = #OutLetKey THEN 1 ELSE 0 END = 1
Group by
dbo.Sal_POSDet.ArtKey,
dbo.ArtWithVendor.ArtCode,
dbo.ArtWithVendor.ArtName
if(#PerformanceType=0 and #MovingType=0)
begin
select * from #temp
order by Pair asc
end
if(#PerformanceType=0 and #MovingType=1)
begin
select * from #temp
order by Pair desc
end
if(#PerformanceType=1 and #MovingType=0)
begin
select * from #temp
order by turnover asc
end
if(#PerformanceType=1 and #MovingType=1)
begin
select * from #temp
order by turnover desc
end
END
Try this...
select TOP(#ArticleNo) *
from #temp
Use:
SELECT TOP(#ArticleNo)
Therefore:
SELECT TOP(#ArticleNo)
dbo.Sal_POSDet.ArtKey,
dbo.ArtWithVendor.ArtCode,
dbo.ArtWithVendor.ArtName,
Sum(isnull(dbo.Sal_POSDet.Qty,0))as Pair,
Sum(isnull(dbo.Sal_POSDet.Total,0)) as TurnOver
into #temp FROM
dbo.Sal_POS INNER JOIN
dbo.Sal_POSDet ON
dbo.Sal_POS.SalesKey = dbo.Sal_POSDet.SalesKey INNER JOIN
dbo.ArtWithVendor ON
dbo.Sal_POSDet.ArtKey = dbo.ArtWithVendor.ArtKey
WHERE
Sal_POS.IsHold=0 and
Sal_POS.SalesDate between #FromDate and #ToDate and
CASE WHEN #ArtKey is null THEN 1 WHEN ArtWithVendor.ArtKey =#ArtKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtCatKey is null THEN 1 WHEN ArtWithVendor.ArtCatKey =#ArtCatKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtGroupKey is null THEN 1 WHEN ArtWithVendor.ArtGroupKey = #ArtGroupKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtTypeKey is null THEN 1 WHEN ArtWithVendor.ArtTypeKey = #ArtTypeKey THEN 1 ELSE 0 END = 1
and CASE WHEN #MaterialKey is null THEN 1 WHEN ArtWithVendor.MaterialKey = #MaterialKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ColorKey is null THEN 1 WHEN ArtWithVendor.ColorKey = #ColorKey THEN 1 ELSE 0 END = 1
and CASE WHEN #VendorKey is null THEN 1 WHEN ArtWithVendor.VendorKey = #VendorKey THEN 1 ELSE 0 END = 1
and CASE WHEN #VendorTypeKey is null THEN 1 WHEN ArtWithVendor.VendorTypeKey = #VendorTypeKey THEN 1 ELSE 0 END = 1
and CASE WHEN #OutLetKey is null THEN 1 WHEN Sal_POS.OutLetKey = #OutLetKey THEN 1 ELSE 0 END = 1
Group by
dbo.Sal_POSDet.ArtKey,
dbo.ArtWithVendor.ArtCode,
dbo.ArtWithVendor.ArtName
Alternatively, add the following before your SELECT query:
IF #ArticleNo IS NOT NULL
BEGIN
SET ROWCOUNT #ArticleNo
END
Then after your SELECT query you need to reset the ROWCOUNT by doing:
IF #ArticleNo IS NOT NULL
BEGIN
SET ROWCOUNT 0
END
Therefore, overall it will be something like:
IF #ArticleNo IS NOT NULL
BEGIN
SET ROWCOUNT #ArticleNo
END
SELECT
dbo.Sal_POSDet.ArtKey,
dbo.ArtWithVendor.ArtCode,
dbo.ArtWithVendor.ArtName,
Sum(isnull(dbo.Sal_POSDet.Qty,0))as Pair,
Sum(isnull(dbo.Sal_POSDet.Total,0)) as TurnOver
into #temp FROM
dbo.Sal_POS INNER JOIN
dbo.Sal_POSDet ON
dbo.Sal_POS.SalesKey = dbo.Sal_POSDet.SalesKey INNER JOIN
dbo.ArtWithVendor ON
dbo.Sal_POSDet.ArtKey = dbo.ArtWithVendor.ArtKey
WHERE
Sal_POS.IsHold=0 and
Sal_POS.SalesDate between #FromDate and #ToDate and
CASE WHEN #ArtKey is null THEN 1 WHEN ArtWithVendor.ArtKey =#ArtKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtCatKey is null THEN 1 WHEN ArtWithVendor.ArtCatKey =#ArtCatKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtGroupKey is null THEN 1 WHEN ArtWithVendor.ArtGroupKey = #ArtGroupKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtTypeKey is null THEN 1 WHEN ArtWithVendor.ArtTypeKey = #ArtTypeKey THEN 1 ELSE 0 END = 1
and CASE WHEN #MaterialKey is null THEN 1 WHEN ArtWithVendor.MaterialKey = #MaterialKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ColorKey is null THEN 1 WHEN ArtWithVendor.ColorKey = #ColorKey THEN 1 ELSE 0 END = 1
and CASE WHEN #VendorKey is null THEN 1 WHEN ArtWithVendor.VendorKey = #VendorKey THEN 1 ELSE 0 END = 1
and CASE WHEN #VendorTypeKey is null THEN 1 WHEN ArtWithVendor.VendorTypeKey = #VendorTypeKey THEN 1 ELSE 0 END = 1
and CASE WHEN #OutLetKey is null THEN 1 WHEN Sal_POS.OutLetKey = #OutLetKey THEN 1 ELSE 0 END = 1
Group by
dbo.Sal_POSDet.ArtKey,
dbo.ArtWithVendor.ArtCode,
dbo.ArtWithVendor.ArtName
IF #ArticleNo IS NOT NULL
BEGIN
SET ROWCOUNT 0
END
However using ROWCOUNT is not ideal as it will mess with your sub-query results.