Speeding up SQL query(s) - sql

New to SQL Server so I am sorry if this is not correctly. We have a number of stored procedures. The one shown below is a good example.
The issue with the query is it works fine until there are thousands of records and it sometimes never returns. I am told this could be performance related and that queries like this could be improved by using local variables. Any insight would be appreciated...thanks
CREATE PROCEDURE [dbo].[Status_GetObjectConfigurationsPr]
#SiteID int,
#AnalogBinary bit,
#UserID int,
#ActionNumber int
AS
DECLARE #ProcName varchar(128),
#ErrorText varchar(200),
#ErrorID int,
#RoleID int
SELECT #RoleID = RoleID
FROM TESUserRole
WHERE UserID = #UserID
SELECT #ProcName = OBJECT_NAME(##PROCID)
SELECT
o.ObjectID,
o.ObjectName,
o.ObjectType,
o.ObjectURI,
o.KeyName,
c.UserDefinedUnits,
o.SiteID,
ts.SiteName,
p.Device_ID,
c.Dimension,
CASE
(SELECT COUNT(ParentObjectID) FROM TESObjectParent
WHERE ChildObjectID IN (o.ObjectID))
WHEN 2
THEN (SELECT TOP 1 b.ParentObjectID
FROM TESObject a
INNER JOIN TESObjectParent b ON a.ObjectID = b.ParentObjectID
WHERE a.ObjectID IN (SELECT ParentObjectID
FROM TESObjectParent
WHERE ChildObjectID IN (o.ObjectID))
AND ObjectType != 8
AND RelationshipType = 7)
WHEN 1
THEN (SELECT TOP 1 ParentObjectID
FROM TESObjectParent
WHERE ChildObjectID = o.ObjectID AND RelationshipType = 7)
END AS ParentObjectId,
CASE
(Select count(ParentObjectID) from TESObjectParent where ChildObjectID in (o.ObjectID) )
When 2 Then ((select top 1 ObjectName from TESObject a inner join TESObjectParent b
on a.ObjectID = b.ParentObjectID where a.ObjectID in
(Select ParentObjectID from TESObjectParent where ChildObjectID in (o.ObjectID))
and ObjectType != 8 and RelationshipType = 7))
When 1 Then PanelName
End
as PanelName
FROM
TESObject o
LEFT OUTER JOIN
TESObjectConfiguration c
ON
o.ObjectID = c.ObjectID
INNER JOIN
TESSite ts
ON
o.SiteID =ts.SiteID
INNER JOIN
TESPanel p
ON
o.Device_ID = p.Device_ID and o.SiteID = p.SiteID
INNER JOIN
TESObjectFamily f
ON
o.CustomFamilyNumber = f.FamilyNumber
INNER JOIN
TESEquipmentRole er
ON
er.FamilyID = f.FamilyID AND er.ObjectType = o.ObjectType
INNER JOIN
TESAction a
ON
er.ActionID = a.ActionID
WHERE
p.IsAppliedToLicense = 1 AND p.IsPanelEnabled = 1
AND
o.SiteID = #SiteID
AND
(c.Property_ID = 85 OR c.Property_ID is NULL)
AND(
(#AnalogBinary = 0 AND o.ObjectType IN (4,5))
OR
(#AnalogBinary = 1 AND o.ObjectType IN (1,2))
)
AND
er.RoleID = #RoleID
AND
a.ActionNumber = #ActionNumber
SET #ErrorID = ##ERROR
IF #ErrorID <> 0
BEGIN
SET #ErrorText = 'Unable to retrieve Object Configuration Information.'
GOTO ErrorHandler
END
---- Error Handling
RETURN 0
ErrorHandler:
BEGIN
RAISERROR ('PROC: %s - %s , Error: %d.', 16, 1, #ProcName, #ErrorText, #ErrorID)
END
RETURN 1

Related

Msg 245, Level 16, State 1, Procedure SYNC_ri_res_to_WC_PersonAddress, Line 24 [Batch Start Line 0] Conversion failed when converting the

When I run the following query:
update ri_res
set name_last = 'onion',
name_first = 'Forest',
addr1 = '2872 Loki Laufeyson',
city = 'Queens',
[state] = 'NY',
zip = '11374',
county = 'West',
phone = '4152366293',
ssn = '912308719',
sex = 'M',
birthplace = 'Madison',
birth_date = '3/1/1947',
uniqueid = newid()
where cono = 'JC' and resno = '216'
I am getting the following error:
Msg 245, Level 16, State 1, Procedure SYNC_ri_res_to_WC_PersonAddress,
Line 24 [Batch Start Line 0] Conversion failed when converting the
varchar value '1094_2' to data type int.
Listed below is the stored procedure:
USE [WestCounty]
GO
/****** Object: StoredProcedure [Base360].[SYNC_ri_res_to_WC_PersonAddress] Script Date: 2/25/2019 9:12:39 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [Base360].[SYNC_ri_res_to_WC_PersonAddress]
#ConoResnos XML
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Payload as XML = #ConoResnos;
/* Address (ri_res address fields) */
INSERT INTO Base360.Address_Base (Address1, Address2, City, AddressStateID, Zipcode, AddressCountyID, EnterpriseID)
select distinct i.addr1, i.addr2, i.city, S.AddressStateID, i.zip, county.AddressCountyID,(select top 1 EnterpriseID from Base360.Facility_Base where FacilityID > 0)
FROM ri_res i with(nolock)
INNER JOIN (SELECT x.value('cono[1]','varchar(4)') as cono, x.value('resno[1]','INT') as resno FROM #Payload.nodes('/Inserted/Row') AS T(x)) as cr
on cr.cono = i.cono and cr.resno = i.resno
LEFT OUTER JOIN [Base360].[AddressState] S ON i.state = S.StateCode
LEFT OUTER JOIN Base360.AddressCounty county on i.county = county.CountyName and S.AddressStateID = county.AddressStateID
LEFT OUTER JOIN [Base360].[Address_Base] A with(nolock)
ON ISNULL(addr1,'') = ISNULL(A.Address1 ,'')
AND isnull(addr2,'') = isnull(A.Address2,'')
AND isnull(S.AddressStateID,'') = ISNULL(A.AddressStateID,'')
AND isnull(i.city,'') = isnull(A.City,'')
AND isnull(SUBSTRING(i.[zip], 1, 5),'') = isnull(SUBSTRING(A.ZipCode,1,5),'')
AND isnull(county.AddressCountyID,'') = ISNULL(A.AddressCountyID,'')
WHERE A.AddressID IS NULL and (i.addr1 is not null or i.addr2 is not null OR i.city is not null or i.state is not null or i.zip is not null or i.county is not null)
UPDATE PA SET EndDAte = GetUTCDate()
FROM ri_res rc with(nolock)
INNER JOIN (SELECT x.value('cono[1]','varchar(4)') as cono, x.value('resno[1]','INT') as resno FROM #Payload.nodes('/Inserted/Row') AS T(x)) as cr
on cr.cono = rc.cono and cr.resno = rc.resno
INNER JOIN Base360.PersonIdentification PID with(nolock) on rc.cono = SUBSTRING(PID.PersonIdentificationValue, 0,(charindex('_',PID.PersonIdentificationValue)))
AND rc.resno = CAST(SUBSTRING(PID.PersonIdentificationValue, (charindex('_',PID.PersonIdentificationValue))+1,10) as int)
AND PID.PersonIdentificationTypeID = -1
INNER JOIN Base360.PersonAddress PA on PID.PersonID = PA.PersonID and PA.AddressTypeID = -2 and PA.EndDate IS NULL
;with addyCTEInsert2 as (
select ROW_NUMBER() OVER (Partition by isnull(A.Address1,''), isnull(A.Address2,''), isnull(A.City,''), ISNULL(A.AddressStateID,''), isnull(SUBSTRING(A.ZipCode,1,5),''), isnull(county.CountyName,'') ORDER BY CreateUTCDate) as RowNum,
A.AddressID, A.Address1, A.Address2, A.City, A.AddressStateID, A.Zipcode, county.AddressCountyID
FROM ri_res i with(nolock)
INNER JOIN (SELECT x.value('cono[1]','varchar(4)') as cono, x.value('resno[1]','INT') as resno FROM #Payload.nodes('/Inserted/Row') AS T(x)) as cr
on cr.cono = i.cono and cr.resno = i.resno
LEFT OUTER JOIN [Base360].[AddressState] S ON i.state = S.StateCode
LEFT OUTER JOIN Base360.AddressCounty county on i.county = county.CountyName and S.AddressStateID = county.AddressStateID
INNER JOIN [Base360].[Address_Base] A with(nolock)
ON ISNULL(addr1,'') = ISNULL(A.Address1 ,'')
AND isnull(addr2,'') = isnull(A.Address2,'')
AND isnull(S.AddressStateID,'') = ISNULL(A.AddressStateID,'')
AND isnull(i.city,'') = isnull(A.City,'')
AND isnull(SUBSTRING(i.[zip], 1, 5),'') = isnull(SUBSTRING(A.ZipCode,1,5),'')
AND isnull(county.AddressCountyID,'') = ISNULL(A.AddressCountyID,'')
WHERE (i.addr1 is not null or i.addr2 is not null OR i.city is not null or i.state is not null or i.zip is not null or i.county is not null)
)
INSERT INTO Base360.PersonAddress ([PersonID], [AddressID], [AddressTypeID], [BeginDate], [EnterpriseID])
select distinct PB.PersonID, AB.AddressID, -2 AS AddressTypeID, GetUTCDate() AS BeginDate, PB.EnterpriseID
FROM ri_res rc with(nolock)
INNER JOIN Base360.PersonIdentification PID with(nolock) on rc.cono = SUBSTRING(PID.PersonIdentificationValue, 0,(charindex('_',PID.PersonIdentificationValue)))
AND rc.resno = CAST(SUBSTRING(PID.PersonIdentificationValue, (charindex('_',PID.PersonIdentificationValue))+1,10) as int)
AND PID.PersonIdentificationTypeID = -1
INNER JOIN [Base360].[Person_Base] PB with(nolock) ON PID.PersonID = PB.PersonID
LEFT OUTER JOIN [Base360].[AddressState] S ON rc.state = S.StateCode
LEFT OUTER JOIN Base360.AddressCounty county on rc.county = county.CountyName and s.AddressStateID = county.AddressStateID
INNER JOIN addyCTEInsert2 AB
ON ISNULL(rc.addr1,'') = ISNULL(AB.Address1 ,'')
AND isnull(rc.addr2,'') = isnull(AB.Address2,'')
AND isnull(S.AddressStateID,'') = ISNULL(AB.AddressStateID,'')
AND isnull(rc.city,'') = isnull(AB.City,'')
AND isnull(SUBSTRING(rc.[zip], 1, 5),'') = isnull(SUBSTRING(AB.ZipCode,1,5),'')
AND isnull(county.AddressCountyID,'') = ISNULL(AB.AddressCountyID,'')
and ab.rownum = 1
INNER JOIN (SELECT x.value('cono[1]','varchar(4)') as cono, x.value('resno[1]','INT') as resno FROM #Payload.nodes('/Inserted/Row') AS T(x)) as cr
on cr.cono = rc.cono and cr.resno = rc.resno
LEFT OUTER JOIN Base360.PersonAddress pa with(nolock) on PB.PersonID = pa.personid and pa.AddressTypeID = -2 and pa.EndDate is null and AB.AddressID = pa.AddressID
WHERE pa.PersonAddressID IS NULL AND (rc.[name_first] IS NOT NULL OR rc.[name_last] IS NOT NULL)
END

optimize complex stored procedure

I have a very complex stored procedure and i am not that strong in SQL, please any one who has a strong SQL expertise and can help me optimize or at least can give me a hint, the procedure selects the inbox messages from database for specific user and it contains many other parameters such as paging and categories and also language input and many other details:
ALTER PROCEDURE [dbo].[Inbox]
#ConfidentialityIds NVARCHAR(100) = '0,1,2,3',
#UrgencyIds NVARCHAR(100) = '0,1,2,3',
#CorrespondenceCategoryIds NVARCHAR(100) = '1,2,3,5,6,7',
#CorrespondenceExtendedCategoryIds NVARCHAR(MAX),
#IsPrivate bit = 0,
#IsSaved bit = 0,
#Importantance VARCHAR(10) = '0, 1',
#UserId uniqueidentifier,
#SelectedPage int = 1,
#PageSize int = 25,
#Now bigint,
#IsImpersonated bit,
#ActualLoggedInUserId uniqueidentifier,
#IsEnglish bit,
#OnlyArchived bit = null,
#replaceNameWithEntName bit,
#entityIds nvarchar(MAX),
#OnlyLate bit = 0,
#Statuses NVARCHAR(100) ='1,2,3,4,5',
#ApplyPageFilter bit = 1,
#IsBundled int,
#showArchivedInCCInbox bit = 0,
#appModuleId INT = 0
WITH RECOMPILE
As
BEGIN
SET transaction isolation level read uncommitted
DECLARE #lFirstRec INT, #lLastRec INT, #lTotalRows INT
SET #lFirstRec = ( #SelectedPage - 1 ) * #PageSize
SET #lLastRec = ( #SelectedPage * #PageSize + 1 )
SET #lTotalRows = #lFirstRec - #lLastRec + 1
DECLARE #isPersonalDelegationAvailable BIT = 0
IF EXISTS(
SELECT 1
FROM DelegatedToEntityUsers d
WHERE d.DelegatedToUserId = #ActualLoggedInUserId
AND d.DelegatedFromUserId = #UserId
AND
(
d.DelegatedToEntityId IS NULL OR d.DelegationType = 1
))
BEGIN
SET #isPersonalDelegationAvailable = 1
END
DECLARE #tblEntities TABLE(Value INT)
INSERT INTO #tblEntities
SELECT Value FROM SplitCommaUniqueValues(#entityIds)
Select * from (
Select (ROW_NUMBER() OVER (ORDER BY K.ActionDate DESC, K.CorrespondenceDate DESC)) AS RowIndex,
Count(*) over () AS TotalCount,*
from (
select (ROW_NUMBER() OVER (PARTITION BY CorrespondenceID Order by CorrespondenceID DESC)) AS CorrId, *
from (
SELECT Distinct * FROM
(
SELECT
CONVERT(VARCHAR(100), R.CorrespondenceActionRecipientID) Id,
A.CorrespondenceActionID ActionId,
(CASE WHEN R.RecipientType IS NULL THEN NULL ELSE CAST(RecipientType AS INT) END) RecipientType,
A.ActionTypeId,
(CASE when #IsEnglish = 1 then ATypes.FriendlyTextEN else ATypes.FriendlyTextAR end) ActionTypeName,
A.ActionCreatedByUserID SentById,
CASE
when #replaceNameWithEntName = 0 then ISNULL(ActionCreatedByUser.ShortName, ActionCreatedByUser.EmployeeName)
when #replaceNameWithEntName = 1 and SentByEntity.EntityID not in (SELECT Value FROM #tblEntities) then case when #IsEnglish = 1 then SentByEntity.EntityNameEn else SentByEntity.EntityNameAR end
when #replaceNameWithEntName = 1 and SentByEntity.EntityID in (SELECT Value FROM #tblEntities) then ISNULL(ActionCreatedByUser.ShortName, ActionCreatedByUser.EmployeeName)
END SentByFrom,
A.WithDelegateFromUserID OnBehalfOfId,
ISNULL(WithDelegateFromUser.ShortName, WithDelegateFromUser.EmployeeName) OnBehalfOfName,
R.UserId SentToId,
CASE
when #replaceNameWithEntName = 0 then ISNULL(SentToUser.ShortName, SentToUser.EmployeeName)
when #replaceNameWithEntName = 1 and SentToEntity.EntityID not in (SELECT Value FROM #tblEntities) then case when #IsEnglish = 1 then SentToEntity.EntityNameEn else SentToEntity.EntityNameAR end
when #replaceNameWithEntName = 1 and SentToEntity.EntityID in (SELECT Value FROM #tblEntities) then isnull(ISNULL(SentToUser.ShortName, SentToUser.EmployeeName), case when #IsEnglish = 1 then SentToEntity.EntityNameEn else SentToEntity.EntityNameAR end)
END SentToName,
R.EntityID SentToEntityId,
SentToEntity.EntityNameAR SentToEntityNameAR,
SentToEntity.EntityNameEN SentToEntityNameEN,
R.Seen,
(CASE WHEN MR.CorrespondenceActionRecipientID IS NOT NULL THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END) IsReadByUser,
CAST(ISNULL(FollowedByUser.IsFollowedByUser, 0) AS BIT) IsFollowedByUser,
(
CASE WHEN EXISTS(SELECT 1 FROM CorrespondenceFollowups
WHERE CorrespondenceID = C.CorrespondenceID
AND UserId = #UserId AND AssignedByUserId IS NOT NULL) THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT) END
) IsAssignedFollowToUser,
(
CASE WHEN EXISTS(SELECT 1 FROM CorrespondenceFollowups
WHERE CorrespondenceID = C.CorrespondenceID
AND AssignedByUserId = #UserId) THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT) END
) IsAssignedFollowByUser,
A.CorrespondenceID,
A.ActionDate,
A.ActionDeadlineDate,
C.CompletionDate,
C.CorrespondenceDeadlineDate CorrDeadlineDate,
C.OwnerUserID CorrOwnerId,
C.ChildNo ChildNo,
OwnerUser.EmployeeName CorrOwnerName,
C.Important,
C.UrgencyId,
C.LetterCorrespondenceId,
(CASE when #IsEnglish = 1 then U.TextEN else U.TextAR end) UrgencyText,
C.ConfidentialityId,
(CASE when #IsEnglish = 1 then Confid.TextEN else Confid.TextAR end) ConfidentialityText,
C.CorrespondenceCategoryId CategoryId,
C.CorrespondenceClassificationID CorrespondenceClassificationID,
(CASE when #IsEnglish = 1 then CCat.TextEN else CCat.TextAR end) CategoryName,
CCat.ColorClass ColorClass,
C.Subject,
c.CorrespondenceFormula,
C.InternalSenderEntityId,
C.InternalRecipientEntityId,
C.[Sequence] [Sequence],
C.Year,
C.CompletionStatus Status,
Null Number,
(CASE WHEN (
(
(A.ActionDeadlineDate IS NOT NULL AND A.ActionDeadlineDate < #Now)
OR
(C.CorrespondenceDeadlineDate IS NOT NULL AND C.CorrespondenceDeadlineDate < #Now)
)
AND
C.[Closed-Archived] = 0) THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END) IsLate,
CAST(0 AS BIT) HasAnyEvents,
C.CreatedByUserId,
CreatedByUser.EmployeeName CreatedByUserName,
CAST(C.CorrespondenceDate AS VARCHAR(50)) CorrDate,
C.CorrespondenceDate,
C.[Closed-Archived] ClosedArchived,
C.IsSaved SavedActionTaken,
((CASE WHEN C.Important = 1 THEN CASE WHEN #IsEnglish = 1 THEN N'Important' ELSE N'هامة' END ELSE '' END) + (CASE WHEN C.Important = 1 AND C.UrgencyID <> 0 THEN CASE WHEN #IsEnglish = 1 THEN N' and ' ELSE N' و ' END ELSE '' END) + (CASE WHEN C.UrgencyID <> 0 THEN (CASE when #IsEnglish = 1 then U.TextEN else U.TextAR end) ELSE '' END)) ImportantUrgencyText,
CAST(C.IsAutoSaved AS BIT) IsAutoSaved,
-- *******************************************************************
rem.ReminderDate as CorrespondenceReminderDateTime,
remAction.ReminderDate as ActionReminderDateTime
FROM (
SELECT * FROM Correspondences CC
WHERE CC.IsDeleted = 0
AND CC.LetterCorrespondenceId IS NULL
AND (CC.ConfidentialityId IN (SELECT [Value] FROM SplitCommaUniqueValues(#ConfidentialityIds)))
AND
( #IsPrivate = 0 OR
(
#IsPrivate = 1 AND CC.IsForPresident = 1
)
)
AND
(
(CC.IsSaved = case when #IsSaved =1 then 1 else CC.IsSaved end)
)
AND (#appModuleId = 0 OR CC.AppModuleId = #appModuleId)
AND (CC.UrgencyID IN (SELECT value FROM SplitCommaUniqueValues(#UrgencyIds)))
AND (CC.Important IN (SELECT value FROM SplitCommaUniqueValues(#Importantance)))
AND CC.CompletionStatus IN(SELECT value FROM SplitComma(#Statuses))
) C
LEFT JOIN CorrespondenceExtendedDetails CorrExt
ON CorrExt.CorrespondenceID = C.CorrespondenceID
LEFT JOIN CorrespondenceActions A
ON C.CorrespondenceID = A.CorrespondenceID
AND A.IsDeleted = 0
AND A.ActionTypeID != 7 -- إنهاء التذكير
LEFT JOIN CorrespondenceActionRecipients R
ON A.CorrespondenceActionID = R.CorrespondenceActionID
AND (
R.AsCopy = 1
)
JOIN Urgencies U
ON C.UrgencyID = U.ID
JOIN ActionTypes ATypes
ON A.ActionTypeID = ATypes.ID
JOIN CorrespondenceCategories CCat
ON C.CorrespondenceCategoryId = CCat.ID
JOIN Confidentialities Confid
ON C.ConfidentialityID = Confid.ID
LEFT JOIN Users ActionCreatedByUser
ON A.ActionCreatedByUserID = ActionCreatedByUser.UserId
LEFT JOIN Users WithDelegateFromUser
ON A.WithDelegateFromUserID = WithDelegateFromUser.UserID
LEFT JOIN Entities SentByEntity
ON A.ActionCreatedByUserEntityId = SentByEntity.EntityID
LEFT JOIN Users SentToUser
ON R.UserId = SentToUser.UserId
LEFT JOIN Entities SentToEntity
ON R.EntityID = SentToEntity.EntityID
LEFT JOIN Users OwnerUser
ON C.OwnerUserID = OwnerUser.UserId
LEFT JOIN Users CreatedByUser
ON C.CreatedByUserID = CreatedByUser.UserId
LEFT JOIN MarkAsReads MR
ON R.CorrespondenceActionRecipientID = MR.CorrespondenceActionRecipientID
AND MR.UserId = #UserId
OUTER APPLY
(
SELECT TOP 1 1 IsFollowedByUser
FROM CorrespondenceFollowups CF
WHERE CF.CorrespondenceId = C.CorrespondenceID
AND CF.UserId = #UserId
AND CF.AssignedByUserId IS NULL
) FollowedByUser
-- *******************************************************************
LEFT JOIN LinkedCorrespondenceSchedules CS on CS.CorrespondenceID = C.CorrespondenceID
LEFT JOIN Reminder rem on rem.ReferenceId=C.CorrespondenceID AND rem.ReferenceType = 1 AND rem.CreatedByUserId=#UserId AND (rem.[Status] = 1 OR rem.[Status] = 2)
Left JOIN Reminder remAction on remAction.ReferenceId = A.CorrespondenceActionID AND remAction.ReferenceType = 2 AND remAction.CreatedByUserId=#UserId AND (remAction.[Status] = 1 OR remAction.[Status] = 2)
-- *******************************************************************
WHERE (
(C.CorrespondenceCategoryId IN (SELECT Value FROM SplitComma(#CorrespondenceCategoryIds)) AND CorrExt.CorrespondenceExtendedCategoryId IS NULL)
OR (CorrExt.CorrespondenceExtendedCategoryId IN (SELECT Value FROM SplitComma(#CorrespondenceExtendedCategoryIds)))
)
AND
(
-- Personal
(
(
(#IsImpersonated = 0 AND R.UserId = #UserId)
OR
(#IsImpersonated = 1 AND R.UserId = #UserId AND #isPersonalDelegationAvailable = 1)
)
AND R.RecipientType = 1 AND R.UserId Is Not null
)
OR
-- Me as Manager (Impersonation mode handled from code by sending the proper Entity Ids.
(
(R.EntityID IN (SELECT Value FROM #tblEntities) AND R.EntityID Is Not null AND R.RecipientType != 1)
)
)
AND C.[Closed-Archived] = Case When #showArchivedInCCInbox = 1 Then 0 Else C.[Closed-Archived] End
AND R.UserTokeAction = 0
AND NOT EXISTS (
SELECT 1 FROM Correspondences CC
INNER JOIN CorrespondenceLinks CL
ON CC.CorrespondenceID = CL.LinkedCorrespondenceID AND CC.CorrespondenceID = C.CorrespondenceID AND CL.LinkTypeID = #IsBundled
)
) T
WHERE T.LetterCorrespondenceId is null
) as ttt
) K where CorrId = 1
)N where (#ApplyPageFilter = 0 OR ( RowIndex > #lFirstRec AND RowIndex < #lLastRec))
Order by
ActionDate DESC, CorrespondenceDate
option(recompile)
END

Catch All Queries with a Table Valued Function

I have a rather long Sql query that needs different where clauses depending on user choices.
I have done some searching, and this seems to be the most comprehensive article on the matter.
However, it doesn't mention the option of using the table valued function to achieve the same effect, and to me, this seems to be the most optimum answer.
Am I missing something?
Here is my catch all query written with the TVF:
--These paramenters will always be passed
declare #tenantId int = 7;
declare #yesterday DateTime = dateadd(day,datediff(day,1,GETUTCDATE()),0);
declare #tomorrow DateTime = dateadd(day,datediff(day,-1,GETUTCDATE()),0);
--These are optional:
declare #parentId int = 230; --In this example, #parentId is populated.
declare #ownedById int = null; --In this example, #ownedBy is not populated.
--Simple if statement:
if #parentId is not null
BEGIN
if #ownedById is not null
BEGIN
Select * from GetItemInfos(#tenantId, #yesterday, #tomorrow)
where ParentId = #parentId and OwnedById = #ownedById;
END
ELSE
Select * from GetItemInfos(#tenantId, #yesterday, #tomorrow)
where ParentId = #parentId;
END
ELSE IF #ownedById is not null
BEGIN
Select * from GetItemInfos(#tenantId, #yesterday, #tomorrow)
where OwnedById = #ownedById;
END
ELSE
Select * from GetItemInfos(#tenantId, #yesterday, #tomorrow);
And here is the TVF:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION GetItemInfos
(
#tenantId int,
#yesterday DateTime,
#tomorrow DateTime
)
RETURNS TABLE
AS
RETURN
(
Select i.Id,
i.AssignedToId,
i.ParentId,
i.OwnedById,
i.Budget,
i.CloseDate,
i.CloseStatusId,
AssignedToName = Concat(anu.FirstName, ' ', anu.LastName),
OwnedByName = Concat(anu2.FirstName, ' ', anu2.LastName),
CloseStatusName = cs.Name,
i.ItemTypeId,
ItemTypeIcon = it.Icon,
i.ImportanceTypeId,
ImportanceTypeDescription = ImportanceTypes.Description,
i.EntityStatusId,
i.DueDate,
IsOverdue =
case when i.CloseStatusId = 1 and i.DueDate <= #yesterday then Cast(1 as bit)
else Cast(0 as bit)
end,
IsDue =
case when i.CloseStatusId = 1 and i.DueDate >= #yesterday and i.DueDate < #tomorrow then cast(1 as bit)
else Cast(0 as bit)
end,
IsClosed = case when (i.CloseStatusId != 1) then cast(1 as bit) else cast(0 as bit) end,
i.Cost,
ItemTypeShowProperties = it.ShowProperties,
ItemTypeSortOrder = it.SortOrder,
PriorityTypeDescription = PriorityTypes.Description,
PriorityTypeSortOrder = PriorityTypes.SortOrder,
i.Name,
i.PriorityTypeId,
Progress = Convert(nvarchar, i.Progress) + '%',
i.SortOrder,
i.StartDate,
StatusTypeName = StatusTypes.Name,
i.TimeEstimate,
TimeScaleTypeName = TimeScaleTypes.Name
from Items i
left join AppUsers au
on i.AssignedToId = au.Id
left join AspNetUsers anu
on au.AspNetUserId = anu.id
left join AppUsers au2
on i.OwnedById = au2.Id
left join AspNetUsers anu2
on au2.AspNetUserId = anu2.id
left join CloseStatuses cs
on i.CloseStatusId = cs.id
left join ItemTypes it
on i.ItemTypeId = it.Id
left join ImportanceTypes
on i.ImportanceTypeId = ImportanceTypes.Id
left join PriorityTypes
on i.PriorityTypeId = PriorityTypes.Id
left join StatusTypes
on i.StatusTypeId = StatusTypes.Id
left join TimeScaleTypes
on i.TimeScaleTypeId = TimeScaleTypes.Id
where i.TenantId = #tenantid
)
GO
EDIT
Based on the comments, this seems to be the best way to write this:
Select * from GetItemInfos(#tenantId, #yesterday, #tomorrow)
where (#parentId is null or ParentId = #parentId) and (#ownedById is null or OwnedById = #ownedById) OPTION(RECOMPILE)

Invalid Object Name - Local SQL Object

The following stored procedure works fine and returns data. However I wanted to also insert the data into a table for debugging before the final select. The code for the insert is commented out just before the final select. The insert uses the exact same select, without the order by, as the data source. However when I run the procedure with the insert uncommented I get an error:
Invalid Object Name BudgetSummaryDetail
I don't why using the object name is fine in the final select but if I try to use it for the insert I get an error. I'm sure there is a reason but I've tried it a bunch of different ways and I can't seem to figure it out. Any help or insight would be most appreciated.
ALTER PROCEDURE [dbo].[rptBudgetSummaryTest]
#Fy AS CHAR(4),
#Index_No AS VARCHAR(MAX) = NULL, -- "IN" - NULL for all; otherwise, comma seperated list of values
#PCA AS VARCHAR(MAX) = NULL, -- "IN" - NULL for all; otherwise, comma seperated list of values
#Appro_Sym AS VARCHAR(MAX) = NULL, -- "IN" - NULL for all; otherwise, comma seperated list of values
#IncludeNonFundedPositions AS BIT = 1,
#OnlyNonZeroPYs AS BIT = 0,
#OnlyNonZeroAllotment AS BIT = 0,
#mrgpcain as dbo.mrgpcain READONLY
AS
IF 1=0 BEGIN
SET FMTONLY OFF
END
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
-- SET XACT_ABORT ON causes the entire transaction to be
-- rolled back on a run-time error instead of just the sql
-- statement that caused the error.
SET XACT_ABORT ON
BEGIN
-- Tally tables for optional multi-value parameters
SELECT Item
INTO #Index_No_ParamValues
FROM [Common].dbo.Split(#Index_No, ',')
IF (SELECT COUNT(*) FROM #Index_No_ParamValues WHERE Item IS NOT NULL) < 1
BEGIN
TRUNCATE TABLE #Index_No_ParamValues
END
SELECT Item
INTO #PCA_ParamValues
FROM [Common].dbo.Split(#PCA, ',')
IF (SELECT COUNT(*) FROM #PCA_ParamValues WHERE Item IS NOT NULL) < 1
BEGIN
TRUNCATE TABLE #PCA_ParamValues
END
SELECT Item
INTO #Appro_Sym_ParamValues
FROM [Common].dbo.Split(#Appro_Sym, ',')
IF (SELECT COUNT(*) FROM #Appro_Sym_ParamValues WHERE Item IS NOT NULL) < 1
BEGIN
TRUNCATE TABLE #Appro_Sym_ParamValues
END
;WITH
BudgetSummaryDetail
AS (
SELECT
tblPCAIn.FY,
tblPCAIn.Index_No,
tblPCAIn.PCA,
tblPCAIn.Obj_Det,
tblPCAIn.Agy_Obj,
tblPCAIn.PYs,
Calc_PYs = IIF(((tblPCAIn.Obj_Det='427' AND tblPCAIn.Agy_Obj='04') OR tblPCAIn.Obj_Det='439') AND (CAST(tblPCAIn.PCA AS INT) BETWEEN 5000 AND 5999),
IIF(tblPCAFl.Fund_Src = 'F', (tblPCAIn.PYs * tblPCAFl.W_Pnct), 0),
(tblPCAIn.PYs * tblPCAFl.Pnct)),
Calc_Allot = IIF(((tblPCAIn.Obj_Det='427' AND tblPCAIn.Agy_Obj='04') OR tblPCAIn.Obj_Det='439') AND (CAST(tblPCAIn.PCA AS INT) BETWEEN 5000 AND 5999),
IIF(tblPCAFl.Fund_Src = 'F', (tblPCAIn.Allotment * tblPCAFl.W_Pnct), 0),
(tblPCAIn.Allotment * tblPCAFl.Pnct)),
tblPCAFl.Appro_Sym,
tblPCAFl.Fund_Src,
tblPCAFl.Fund_No,
tblPCAFl.Method,
tblPCAFl.Project,
PCT = ROUND(tblPCAFl.Pnct * 100, 0)
FROM
dbo.tblIndex AS tblIndex
INNER JOIN #mrgpcain AS tblPCAIn ON
tblPCAIn.FY = tblIndex.FY AND
tblPCAIn.Index_No = tblIndex.Index_No
INNER JOIN dbo.tblPCA AS tblPCA ON
tblPCA.FY = tblPCAIn.FY AND
tblPCA.PCA = tblPCAIn.PCA
INNER JOIN dbo.tblPCAFl AS tblPCAFl ON
tblPCAFl.FY = tblPCA.FY AND
tblPCAFl.PCA = tblPCA.PCA
INNER JOIN dbo.tblAppro AS tblAppro ON
tblAppro.FY = tblPCAFl.FY AND
tblAppro.Appro_Sym = tblPCAFl.Appro_Sym
LEFT JOIN #Index_No_ParamValues ON
tblIndex.Index_No = #Index_No_ParamValues.Item
LEFT JOIN #PCA_ParamValues ON
tblPCAIn.PCA = #PCA_ParamValues.Item
LEFT JOIN #Appro_Sym_ParamValues ON
tblAppro.Appro_Sym = #Appro_Sym_ParamValues.Item
WHERE
(#Index_No_ParamValues.Item IS NOT NULL OR NOT EXISTS (SELECT TOP 1 Item FROM #Index_No_ParamValues)) AND
(#PCA_ParamValues.Item IS NOT NULL OR NOT EXISTS (SELECT TOP 1 Item FROM #PCA_ParamValues)) AND
(#Appro_Sym_ParamValues.Item IS NOT NULL OR NOT EXISTS (SELECT TOP 1 Item FROM #Appro_Sym_ParamValues)) AND
(((#IncludeNonFundedPositions = 0) AND
(tblPCA.PCA <> '02727')
) OR (#IncludeNonFundedPositions = 1)) AND
(((#OnlyNonZeroPYs = 1) AND
(tblPCAIn.PYs <> 0.0)
) OR (#OnlyNonZeroPYs = 0)) AND
(((#OnlyNonZeroAllotment = 1) AND
(tblPCAIn.Allotment <> 0)
) OR (#OnlyNonZeroAllotment = 0))
)
--DELETE FROM tblBS_Test
--INSERT INTO tblBS_Test
--SELECT * FROM (
--SELECT
-- tblIndex.Dept_Id,
-- tblIndex.Dpty_Id,
-- tblIndex.Brch_Id,
-- tblIndex.Div_Id,
-- detail.Index_No,
-- tblIndex.Index_Title,
-- detail.PCA,
-- tblPCA.PCA_Title,
-- PROGLINK = REPLACE(tblPCA.Program+tblPCA.Element+tblPCA.Component+tblPCA.Task, '', '0'),
-- FUNDLINK = tblPCAFl.Appro_Sym+tblPCAFl.Fund_Src+tblPCAFl.Fund_No+tblPCAFl.Method+ IIF(tblPCAFl.Project = SPACE(6), SPACE(8), tblPCAFl.Project+'00'),
-- tblAppro.Ref,
-- detail.Obj_Det,
-- detail.Agy_Obj,
-- PYs,
-- POS = IIF(((detail.Obj_Det = '003') AND (RTRIM(detail.Agy_Obj) = '')), detail.Calc_PYs, 0.0),
-- Calc_PYs = detail.Calc_PYs,
-- detail.Calc_Allot,
-- PCT
--FROM
-- BudgetSummaryDetail AS detail
-- INNER JOIN dbo.tblIndex AS tblIndex ON
-- tblIndex.FY = detail.FY AND
-- tblIndex.Index_No = detail.Index_No
-- INNER JOIN dbo.tblPCA AS tblPCA ON
-- tblPCA.FY = detail.FY AND
-- tblPCA.PCA = detail.PCA
-- INNER JOIN dbo.tblPCAFl AS tblPCAFl ON
-- tblPCAFl.FY = tblPCA.FY AND
-- tblPCAFl.PCA = tblPCA.PCA AND
-- tblPCAFl.Appro_Sym = detail.Appro_Sym AND
-- tblPCAFl.Fund_Src = detail.Fund_Src AND
-- tblPCAFl.Fund_No = detail.Fund_No AND
-- tblPCAFl.Method = detail.Method AND
-- tblPCAFl.Project = detail.Project
-- INNER JOIN dbo.tblAppro AS tblAppro ON
-- tblAppro.FY = tblPCAFl.FY AND
-- tblAppro.Appro_Sym = tblPCAFl.Appro_Sym
-- INNER JOIN dbo.tblAgyDE AS tblAgyDE ON
-- tblAgyDE.Obj_Det = detail.Obj_Det AND
-- tblAgyDE.Agy_Obj = detail.Agy_Obj
-- INNER JOIN dbo.tblObjDe AS tblObjDe ON
-- tblObjDe.Obj_Det = tblAgyDE.Obj_Det
-- INNER JOIN dbo.tblCat AS tblCat ON
-- tblCat.Category = tblObjDe.Category) as myda
SELECT
tblIndex.Dept_Id,
tblIndex.Dpty_Id,
tblIndex.Brch_Id,
tblIndex.Div_Id,
detail.Index_No,
tblIndex.Index_Title,
detail.PCA,
tblPCA.PCA_Title,
PROGLINK = REPLACE(tblPCA.Program+tblPCA.Element+tblPCA.Component+tblPCA.Task, '', '0'),
FUNDLINK = tblPCAFl.Appro_Sym+tblPCAFl.Fund_Src+tblPCAFl.Fund_No+tblPCAFl.Method+ IIF(tblPCAFl.Project = SPACE(6), SPACE(8), tblPCAFl.Project+'00'),
tblAppro.Ref,
detail.Obj_Det,
detail.Agy_Obj,
PYs,
POS = IIF(((detail.Obj_Det = '003') AND (RTRIM(detail.Agy_Obj) = '')), detail.Calc_PYs, 0.0),
Calc_PYs = detail.Calc_PYs,
detail.Calc_Allot,
PCT
FROM
BudgetSummaryDetail AS detail
INNER JOIN dbo.tblIndex AS tblIndex ON
tblIndex.FY = detail.FY AND
tblIndex.Index_No = detail.Index_No
INNER JOIN dbo.tblPCA AS tblPCA ON
tblPCA.FY = detail.FY AND
tblPCA.PCA = detail.PCA
INNER JOIN dbo.tblPCAFl AS tblPCAFl ON
tblPCAFl.FY = tblPCA.FY AND
tblPCAFl.PCA = tblPCA.PCA AND
tblPCAFl.Appro_Sym = detail.Appro_Sym AND
tblPCAFl.Fund_Src = detail.Fund_Src AND
tblPCAFl.Fund_No = detail.Fund_No AND
tblPCAFl.Method = detail.Method AND
tblPCAFl.Project = detail.Project
INNER JOIN dbo.tblAppro AS tblAppro ON
tblAppro.FY = tblPCAFl.FY AND
tblAppro.Appro_Sym = tblPCAFl.Appro_Sym
INNER JOIN dbo.tblAgyDE AS tblAgyDE ON
tblAgyDE.Obj_Det = detail.Obj_Det AND
tblAgyDE.Agy_Obj = detail.Agy_Obj
INNER JOIN dbo.tblObjDe AS tblObjDe ON
tblObjDe.Obj_Det = tblAgyDE.Obj_Det
INNER JOIN dbo.tblCat AS tblCat ON
tblCat.Category = tblObjDe.Category
ORDER BY
tblIndex.Dept_Id,
tblIndex.Dpty_Id,
tblIndex.Brch_Id,
tblIndex.Div_Id,
detail.Index_No,
detail.PCA,
tblPCAFl.Appro_Sym+tblPCAFl.Fund_Src+tblPCAFl.Fund_No+tblPCAFl.Method+ IIF(tblPCAFl.Project = SPACE(6), SPACE(8), tblPCAFl.Project+'00'),
detail.Obj_Det,
detail.Agy_Obj
IF Object_id('tempdb..#Index_No_ParamValues') IS NOT NULL
BEGIN
DROP TABLE #Index_No_ParamValues;
END
IF Object_id('tempdb..#PCA_ParamValues') IS NOT NULL
BEGIN
DROP TABLE #PCA_ParamValues;
END
IF Object_id('tempdb..#Appro_Sym_ParamValues') IS NOT NULL
BEGIN
DROP TABLE #Appro_Sym_ParamValues;
END
RETURN 0
END
GO

Join unique ID's from another table

Here is the story: I have to implement filter. And in this filter there are certain categories I filter by.
One of the filters is "favourite" filter (#includeFavourites ).
I have this huge SQL with paging and sorting and everything.
Now, when "includeFavourites" option in filter is clicked, then I also have to select unique ID's from different table (this entries are stored in different datatable), where favourites are stored.
I have tried left outer join, but it returns "number of favourites" records for each record in primary table. Coalesce didn't help at all.
Here is my SQL:
--this is needed because stored procedure must know how many days are selected
DECLARE #daysCount int
SET #daysCount = 0
IF (#mon IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#tue IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#wed IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#thu IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#fri IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#sat IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#sun IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
-- Insert statements for procedure here
SELECT * FROM (
SELECT ROW_NUMBER() OVER
(
ORDER BY
CASE WHEN #OrderBy = 'ND' THEN title END DESC,
CASE WHEN #OrderBy = 'NA' THEN title END,
CASE WHEN #OrderBy = '' THEN title END,
CASE WHEN #OrderBy = 'RD' THEN authorRating END DESC,
CASE WHEN #OrderBy = 'RA' THEN authorRating
) AS Row,
Articles.ArticleId, Articles.userId, Articles.timestamp as datePosted, users.screenName,
defaultSmallImagePath, authorRating, ArticleCosts, title,
FROM Articles
LEFT OUTER JOIN
Users on Articles.userId = Users.userId
LEFT OUTER JOIN
ArticleAdditionalInformation ON ArticleAdditionalInformation.ArticleId = Articles.ArticleId
--JOIN FOR CONTINENT
LEFT OUTER JOIN
Codings as Continent ON Continent.codingKeyId = ArticleAdditionalInformation.continentId AND Continent.languageId = #languageId
-- JOIN FOR COUNTRY
LEFT OUTER JOIN
CodingsAssociated as Country ON Country.codingKeyId = ArticleAdditionalInformation.countryId AND Country.languageId = #languageId
-- JOIN FOR Article TRANSLATION DATA
LEFT OUTER JOIN
ArticlesTranslations ON ArticlesTranslations.ArticleId = Articles.ArticleId AND ArticlesTranslations.languageId=#languageId
LEFT OUTER JOIN
ArticleCategories ON ArticleCategories.ArticleId = Articles.ArticleId
WHERE
(
ArticleCategories.categorieId =1 OR ArticleCategories.categorieId =2 OR
ArticleCategories.categorieId =3 OR ArticleCategories.categorieId =4 OR
ArticleCategories.categorieId = 5
) AND
(ArticlesTranslations.title LIKE '%' + #searchString + '%' OR #searchString IS NULL)
-- COST filter
AND
(ArticleCosts < #cost OR #cost = 0)
AND
(ArticleCosts > 0 OR #cost = 0)
--END cost filter
-- EXCLUDE already stored for selected days
AND Articles.ArticleId -- exclude these ArticleIds
NOT IN
(
SELECT DailyContent.ArticleId
FROM DailyContent
WHERE
sectionId=#sectionId AND
(
weekDayId=#mon OR
weekDayId=#tue OR
weekDayId=#wed OR
weekDayId=#thu OR
weekDayId=#fri OR
weekDayId=#sat OR
weekDayId=#sun
)
GROUP BY
DailyContent.ArticleId
HAVING
(COUNT(sectionId) = #daysCount)
)
-- END exclude
) p
WHERE (Row > #startRowIndex AND Row <=#startRowIndex + #pageSize)
ORDER BY Row
END
So, I would only like to include unique articleIds from favourite table, when #includeFavourites parameter is not null.
Any hint would be greatly appreciated ;)
I am using SQL server 2008.
Try this one -
DECLARE #daysCount INT
SELECT #daysCount =
ISNULL(#mon, 0) + -- if #mon = 1, #tue = 2, .... 1 + (2-1)=1 + (3-2)=1 + ...
ISNULL(#tue - 1, 0) +
ISNULL(#wed - 2, 0) +
ISNULL(#thu - 3, 0) +
ISNULL(#fri - 4, 0) +
ISNULL(#sat - 5, 0) +
ISNULL(#sun - 6, 0)
SELECT *
FROM (
SELECT ROW_NUMBER() OVER
(
ORDER BY
CASE WHEN #OrderBy = 'ND' THEN title END DESC,
CASE WHEN #OrderBy IN ('NA', '') THEN title END,
CASE WHEN #OrderBy = 'RD' THEN authorRating END DESC,
CASE WHEN #OrderBy = 'RA' THEN authorRating
) AS [Row]
, a.ArticleId
, a.userId
, a.[timestamp] as datePosted
, u.screenName
, defaultSmallImagePath
, authorRating
, ArticleCosts
, title
FROM dbo.Articles a -- always use schema and alias
LEFT JOIN dbo.Users u on a.userId = u.userId -- OUTER is unnecessary
LEFT JOIN dbo.ArticleAdditionalInformation aai ON aai.ArticleId = a.ArticleId
LEFT JOIN dbo.Codings cd ON cd.codingKeyId = aai.continentId AND cd.languageId = #languageId
LEFT JOIN dbo.CodingsAssociated c ON c.codingKeyId = aai.countryId AND c.languageId = #languageId
LEFT JOIN dbo.ArticlesTranslations at ON at.ArticleId = a.ArticleId AND at.languageId = #languageId
LEFT JOIN dbo.ArticleCategories ac ON ac.ArticleId = a.ArticleId
WHERE ac.categorieId IN (1, 2, 3, 4, 5)
AND (
at.title LIKE '%' + #searchString + '%'
OR
#searchString IS NULL
)
AND (ArticleCosts < #cost OR #cost = 0)
AND (ArticleCosts > 0 OR #cost = 0)
AND a.ArticleId NOT IN (
SELECT dc2.ArticleId
FROM dbo.DailyContent dc2
WHERE sectionId = #sectionId
AND (
weekDayId % #daysCount = 0 -- possible it's works
--weekDayId = #mon OR
--weekDayId = #tue OR
--weekDayId = #wed OR
--weekDayId = #thu OR
--weekDayId = #fri OR
--weekDayId = #sat OR
--weekDayId = #sun
)
GROUP BY dc2.ArticleId
HAVING COUNT(sectionId) = #daysCount
)
) p
WHERE [Row] BETWEEN #startRowIndex AND #startRowIndex + #pageSize
--ORDER BY [Row] -- ROW_COUNT already sorted your rows