SQL Server case in where clause conditionally - sql

select *
from someTable
where currencyid = #currencyid --CaseA
or (Currencyid in (8,11) or (#Currencyid = 0)) --CaseB
How to modify such query so that when #currencyid = 0 the condition will be set on ONLY CaseB while others set as CaseA?
For example:
if #currencyid = 0 then the end query to be executed is
select *
from someTable
where currencyid = (Currencyid in (8,11) or (#Currencyid = 0))
if #currencyid = 8 then the end query to be executed is
select *
from someTable
where currencyid = #currencyid

SELECT *
FROM someTable
WHERE (currencyid = #Currencyid AND #Currencyid != 0)
OR (Currencyid IN (8, 11) AND #Currencyid = 0)
--OPTION(RECOMPILE)

Related

Conversion failed Error SQL Date format Mismatch with C# Datatable datetime fromat depending on system calender setting

We have a Stored Procedure in SQL Server which expects datetime column to be in MMddyyyy format and results in error
Conversion failed when converting date and/or time from character string.
whenever the system calendar setting is set to ddMMyyyy format. The same SP works fine if other date format is set for the system such as dd-MMM-yyyy works fine and returns no error. SP throws error when the calender setting is changed to ddMMyyyy format. It will work fine for dates below 12 as it takes the first digits as month but fails when higher dates like 15 or 28 is given. I am trying to find a solution so that it will work for all calendar settings as I cannot restrict the end users from changing their calendar settings. Please help me ...
Here is my SP
CREATE PROCEDURE [dbo].[usp_704000]
-- Add the parameters for the stored procedure here
#Dt uttTrnBRS readonly,
#Dt1 uttTrnBRS1 readonly
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
Declare #RowStatus Int
Declare #TrnId Int
Declare #DocNo Varchar(15)
Declare #NextNo Int
Declare #Return SmallInt
Select #RowStatus = MAX(RowStatus), #Return = 0, #TrnId = 0
From #Dt T0
BEGIN TRANSACTION
--NEW Mode Handle the Insertion of New Records
IF (#RowStatus = 2)
BEGIN
BEGIN TRY
Insert into TrnBRS (CmpId, FinYear, FYPrd, DocId, SeriesId, DocDate, DocRef, DocStatus, BankCode, BankName, BankAcNo, AcId, AcCode,
AcDesc, BankAcId, EndDt, EndBalAmt, LastRcnDt, BalAmt, Diff, Remarks, BranchCode, BaseId, CUserId, CreateDt)
Select T0.CmpId, T2.FinYear, T2.FYPrdId FYPrd, T3.DocId, T0.SeriesId, Cast(T0.DocDate as Date) DocDate, T0.DocRef, '3' DocStatus,
T0.BankCode, T0.BankName, T0.BankAcNo, T0.AcId, T0.AcCode, T0.AcDesc, T0.BankAcId,
Cast(T0.EndDt as Date) EndDt, ISNULL(T0.EndBalAmt, 0) EndBalAmt, Cast(T0.LastRcnDt as Date) LastRcnDt, ISNULL(T0.BalAmt, 0) BalAmt, ISNULL(T0.Diff, 0) Diff,
T0.Remarks, T3.BranchCode, T3.BaseId, T0.CUserId, GetDate() CreateDt
From #Dt T0 Cross Join CmpMst T1
Left Join FYPrdMst T2 ON T0.DocDate Between T2.PrdFrom and T2.PrdTo
Inner Join (Select T0.DocId, T0.BaseId, T1.SeriesId, T1.SFinYear, T1.EFinYear, T0.BranchCode
From DocNum T0 Inner Join DocNum1 T1 ON T0.DocId = T1.DocId
Where T0.BaseId = 34) T3 ON T2.FinYear Between T3.SFinYear and ISNULL(T3.EFinYear, 3000)
Where T0.RowStatus = 2;
IF (##ERROR = 0)
SET #TrnId = ##IDENTITY;
IF (##ERROR = 0)
Insert into TrnBRS1 (TrnId, LineNum, BranchCode, PDocNo, PDocDate, PDocRef, PRefDate, DrAmtLC, CrAmtLC, Narration, ClearAmt, BankDt, PTrnId, PBaseId, PDocId,
JnlBaseId, JnlDocId, JnlDocNo, JnlTrnId, JnlLineNum, AdjEntry, Notes, RowIndex)
Select #TrnId TrnId, ROW_NUMBER() OVER (Order by T0.RowIndex) LineNum, T0.BranchCode, T0.PDocNo, Cast(T0.PDocDate as Date) PDocDate, T0.PDocRef,
Cast(T0.PRefDate as Date) PRefDate, T0.DrAmtLC, T0.CrAmtLC, T0.Narration, T0.ClearAmt, Cast(T0.BankDt as Date) BankDt, T0.PTrnId, T0.PBaseId, T0.PDocId,
T0.JnlBaseId, T0.JnlDocId, T0.JnlDocNo, T0.JnlTrnId, T0.JnlLineNum, T0.AdjEntry, T0.Notes, ROW_NUMBER() OVER (Order by T0.RowIndex) RowIndex
From #Dt1 T0
Where ISNULL(T0.IsCheck, 'N') = 'Y'; -- and ISDATE(CONVERT(Varchar(10), T0.BankDt, 111)) = 1;
IF (##ERROR = 0)
Insert into TrnBRS2 (TrnId, LineNum, BranchCode, PDocNo, PDocDate, PDocRef, PRefDate, DrAmtLC, CrAmtLC, Narration, PTrnId, PBaseId, PDocId,
JnlBaseId, JnlDocId, JnlDocNo, JnlTrnId, JnlLineNum, Notes, RowIndex)
Select #TrnId TrnId, ROW_NUMBER() OVER (Order by T0.RowIndex) LineNum, T0.BranchCode, T0.PDocNo, T0.PDocDate, T0.PDocRef,
T0.PRefDate, T0.DrAmtLC, T0.CrAmtLC, T0.Narration, T0.PTrnId, T0.PBaseId, T0.PDocId,
T0.JnlBaseId, T0.JnlDocId, T0.JnlDocNo, T0.JnlTrnId, T0.JnlLineNum, T0.Notes, ROW_NUMBER() OVER (Order by T0.RowIndex) RowIndex
From #Dt1 T0
Where ISNULL(T0.IsCheck, 'N') = 'N'; -- and ISDATE(CONVERT(Varchar(10), T0.BankDt, 111)) = 1;
IF (##ERROR = 0)
Update TrnJnl1
SET RecnDt = T1.BankDt,
RecnSys = 'Y', RecnTrnId = #TrnId, RecnType = 1
From TrnJnl1 T0 Inner Join TrnBRS1 T1 ON T0.TrnId = T1.JnlTrnId and T0.LineNum = T1.JnlLineNum and T1.TrnId = #TrnId;
IF (##ERROR = 0)
Select #NextNo = T1.NextNo + 1,
#DocNo = ISNULL(T1.Prefix, '') + REPLICATE('0', T1.NumLen-LEN(CAST(#NextNo as VARCHAR(5))))+CAST(#NextNo as VARCHAR(5)) +
ISNULL(T1.Suffix, '')
From TrnBRS T0 Inner Join DocNum1 T1 ON T0.DocId = T1.DocId and T0.SeriesId = T1.SeriesId
Where T0.TrnId = #TrnId
IF (##ERROR = 0)
Insert into BankMst3 (BankAcId, BRDate, AcId, BRAmtLC, CUserId, CreateDate)
Select T0.BankAcId, T0.EndDt, T0.AcId, T0.EndBalAmt, T0.CUserId, GetDate() CreateDate
From TrnBRS T0
Where T0.TrnId = #TrnId;
IF (##ERROR = 0)
Update DocNum1
SET NextNo = #NextNo
From DocNum1 T0 Inner Join TrnBRS T1 ON T0.DocID = T1.DocID and T0.SeriesId = T1.SeriesId and T1.TrnId = #TrnId
IF (##ERROR = 0)
Update TrnBRS SET DocNo = #DocNo Where TrnId = #TrnId
IF (##ERROR = 0)
BEGIN
COMMIT TRANSACTION;
Select 0 RetVal, #TrnId TrnId, 'Transaction Saved...' ErrMsg, 0 ErrType;
RETURN
END
END TRY
BEGIN CATCH
BEGIN
ROLLBACK TRANSACTION;
SELECT -1 RetVal, #TrnId TrnId, ERROR_MESSAGE() AS ErrMsg, 1 ErrType
RETURN
END
END CATCH
END
ELSE
BEGIN
BEGIN TRY
Insert into TrnBRS (CmpId, FinYear, FYPrd, DocId, SeriesId, DocDate, DocRef, DocStatus, CancelState, CanclTrnId, EndDt, EndBalAmt,
LastRcnDt, BalAmt, Diff, Remarks, BaseId, CUserId, CreateDt)
Select T0.CmpId, T0.FinYear, T0.FYPrd, T0.DocId, T0.SeriesId, T0.DocDate, T0.DocRef, '3' DocStatus, 'N' CancelState, T0.TrnId CanclTrnId,
T0.EndDt, ISNULL(T0.EndBalAmt, 0) EndBalAmt, T0.LastRcnDt, ISNULL(T0.BalAmt, 0) BalAmt, ISNULL(T0.Diff, 0) Diff,
T0.Remarks, T0.BaseId, T0.CUserId, GetDate() CreateDt
From TrnBRS T0 Inner Join #Dt T1 ON T0.TrnId = T1.TrnId
Where T1.RowStatus = 3;
SET #TrnId = ##IDENTITY;
Update TrnBRS
SET CancelState = 'Y', DocStatus = '4', CanclTrnId = #TrnId
From TrnBRS T0 Inner Join #Dt T1 ON T0.TrnId = T1.TrnId and T1.RowStatus = 3;
Insert into TrnBRS1 (TrnId, LineNum, BranchCode, PDocNo, PDocDate, PDocRef, PRefDate, DrAmtLC, CrAmtLC, Narration, ClearAmt,
BankDt, PTrnId, PBaseId, PDocId, JnlBaseId, JnlDocId, JnlDocNo, JnlTrnId, JnlLineNum, AdjEntry, Notes, RowIndex)
Select #TrnId TrnId, T0.LineNum, T0.BranchCode, T0.PDocNo, T0.PDocDate, T0.PDocRef, T0.PRefDate, T0.DrAmtLC, T0.CrAmtLC,
T0.Narration, T0.ClearAmt *-1, T0.BankDt, T0.PTrnId, T0.PBaseId, T0.PDocId, T0.JnlBaseId, T0.JnlDocId, T0.JnlDocNo,
T0.JnlTrnId, T0.JnlLineNum, T0.AdjEntry, T0.Notes, T0.RowIndex
From TrnBRS1 T0 Inner Join #Dt T1 ON T0.TrnId = T1.TrnId and T1.RowStatus = 3;
Update TrnJnl1
SET RecnDt = NULL, RecnSys = NULL, RecnTrnId = NULL, RecnType = NULL
From TrnJnl1 T0 Inner Join TrnBRS1 T1 ON T0.TrnId = T1.JnlTrnId and T0.LineNum = T1.JnlLineNum and T1.TrnId = #TrnId
Select #NextNo = T1.NextNo + 1,
#DocNo = ISNULL(T1.Prefix, '') +
Substring(Cast(Year(T0.DocDate) as VARCHAR(4)),3,2) + REPLICATE('0', T1.NumLen-LEN(CAST(#NextNo as VARCHAR(5))))+CAST(#NextNo as VARCHAR(5)) +
ISNULL(T1.Suffix, '')
From #Dt T0 Inner Join DocNum1 T1 ON T0.DocId = T1.DocId
Update DocNum1
SET NextNo = #NextNo
From DocNum1 T0 Inner Join #Dt T1 ON T0.DocID = T1.DocID
IF (##ERROR <> 0) RETURN ##ERROR
Update TrnBRS SET DocNo = #DocNo Where TrnId = #TrnId
IF (##ERROR <> 0) RETURN ##ERROR
BEGIN
COMMIT TRANSACTION;
Select 0 RetVal, #TrnId TrnId, 'Transaction Reversed...' ErrMsg, 0 ErrType;
RETURN
END
END TRY
BEGIN CATCH
BEGIN
ROLLBACK TRANSACTION
SELECT -1 RetVal, #TrnId TrnId, ERROR_MESSAGE() AS ErrMsg, 1 ErrType
RETURN
END
END CATCH
END
END
I had tried to convert the ddMMyyyy format(103) using the convert statement SELECT CONVERT(DATE, T1.BankDt, 103) instead of T1.BankDt(which is the datetime field we are trying to manipulate) but didn't succeed. It still throws error saying conversion failed for dates above 12 as it expects dates in MMddyyyy format
EDIT 2
Thank You all for the supports...
I had find the issue at last, the real issue was in another stored procedure which is used to populate the initial value in which the BankDt field was populated with '' empty string so that the field is treated as character string instead of date field. I had changed '' BankDt to Convert(Date,null,103) BankDt ... Now everything works fine
the real issue was in another stored procedure which is used to populate the initial value in which the BankDt field was populated with '' empty string so that the field is treated as character string instead of date field. I had changed
'' BankDt
to
Convert(Date,null,103) BankDt
... Now everything works fine

How to replace where clause with a function and use it in stored procedures?

I have two stored procedures that they have the same where clause, one of them is use for pagination:
ALTER PROCEDURE [dbo].[ret_PayrollCalculations_GetPagedFilteredPersonnels]
(
#SortField varchar(512),
#PageNo int,
#PageSize int,
#CalculationCommandType int,
#StartWorkingPeriodId int,
#StartYear int,
#EndWorkingPeriodId int,
#EndYear int,
#Status int,
#SalariedGuid uniqueidentifier,
#SalariedType int,
#OfficeNumber varchar(64),
#SalariedResultSetId int,
#Keyword nvarchar(2024),
#OperationalUnitIds [dbo].[ListOfID] READONLY
)
AS
DECLARE #AccessibleSalariedGuids [dbo].[ListOfGuid]
IF EXISTS (SELECT * FROM #OperationalUnitIDs)
BEGIN
INSERT INTO #AccessibleSalariedGuids
SELECT FeatureGuid FROM prs_OperationalUnitFeatures
WHERE
OperationalUnitID in (SELECT * FROM #OperationalUnitIDs) AND
FeatureFlag IN (2,4)
END
ELSE BEGIN
INSERT INTO #AccessibleSalariedGuids
SELECT [Guid] FROM ret_vwSalaried
END
DECLARE #OffsetRows INT = CASE WHEN #PageNo = 1 THEN 0 ELSE (#PageNo - 1) * #PageSize END;
DECLARE #TotalCount INT;
WITH Result AS(
SELECT
CASE
WHEN #SortField = N'[FullName]' THEN ROW_NUMBER() OVER (ORDER BY salaried.[FullName])
WHEN #SortField = N'[FullName] DESC' THEN ROW_NUMBER() OVER (ORDER BY salaried.[FullName] DESC)
WHEN #SortField = N'[WorkingPeriodTitle]' THEN ROW_NUMBER() OVER (ORDER BY calcs.[Year],workingPeriods.[Index])
WHEN #SortField = N'[WorkingPeriodTitle] DESC' THEN ROW_NUMBER() OVER (ORDER BY calcs.[Year] DESC,workingPeriods.[Index] DESC)
WHEN #SortField = N'[PersonnelNo]' THEN ROW_NUMBER() OVER (ORDER BY salaried.[PersonnelNo])
WHEN #SortField = N'[PersonnelNo] DESC' THEN ROW_NUMBER() OVER (ORDER BY salaried.[PersonnelNo] DESC)
END AS [RowNumber],
calcs.[Guid],
calcs.[CalculationCommandGuid],
calcs.[SalariedGuid],
salaried.[PersonnelNo],
salaried.[FullName] AS [PersonnelFullName],
command.[Type] [CommandType],
salaried.[SalariedType],
workingPeriods.Title AS [WorkingPeriodTitle],
command.[MainYear] AS [Year],
command.[Approved],
command.[FinalApproved]
FROM
ret_PayrollCalculationCommands command INNER JOIN
ret_PayrollCalculations calcs ON calcs.[CalculationCommandGuid] = command.[Guid] INNER JOIN
ret_vwSalaried salaried ON calcs.[SalariedGuid] = salaried.[Guid] INNER JOIN
prs_workingPeriods workingPeriods ON workingPeriods.[Id] = command.[MainWorkingPeriodID]
WHERE
ISNULL(calcs.[MainCalculation],0) = 1 AND
ISNULL(command.[Deleted],0)=0 AND
(#Keyword = '' OR salaried.PersonnelNo = #Keyword OR salaried.FullName LIKE N'%' + #Keyword + '%' OR salaried.FullNameReversed LIKE N'%' + #Keyword + '%') AND
(ISNULL(#calculationCommandType, 0) = 0 OR command.[Type] = #calculationCommandType) AND
(ISNULL(#StartYear, 0) = 0 OR command.[MainYear] >= #StartYear) AND
(ISNULL(#StartWorkingPeriodId, 0) = 0 OR command.[MainWorkingPeriodID] >= #StartWorkingPeriodId) AND
(ISNULL(#EndYear, 0) = 0 OR command.[MainYear] <= #EndYear) AND
(ISNULL(#EndWorkingPeriodId, 0) = 0 OR command.[MainWorkingPeriodID] <= #EndWorkingPeriodId) AND
(ISNULL(#Status, -1) = -1 OR command.[Approved] = #Status) AND
(ISNULL(#SalariedType, -1) = -1 OR salaried.[SalariedType] = #SalariedType) AND
(ISNULL(#SalariedGuid,'00000000-0000-0000-0000-000000000000') = '00000000-0000-0000-0000-000000000000' OR calcs.[SalariedGuid] = #SalariedGuid) AND
(#OfficeNumber IS NULL OR salaried.[OfficeNumber] LIKE '%'+#OfficeNumber+'%') AND
(ISNULL(#SalariedResultSetId, -1) = -1 OR calcs.[SalariedGuid] IN (SELECT [SalariedGuid] FROM ret_SalariedResultSetItems WHERE SalariedResultSetID = #SalariedResultSetId)) AND
(calcs.[SalariedGuid] IN (SELECT * FROM #AccessibleSalariedGuids))
), TableForTotalCount AS (SELECT COUNT(*) As TotalCount FROM Result)
SELECT
(SELECT TOP 1 TotalCount FROM TableForTotalCount) AS TotalCount,
*
FROM Result
ORDER BY
[RowNumber]
OFFSET #OffsetRows ROWS
FETCH NEXT #PageSize ROWS ONLY
and another one supposed to return some Guids
ALTER PROCEDURE [dbo].[ret_PayrollCalculations_GetFilteredPersonnels]
(
#CalculationCommandType int,
#StartWorkingPeriodId int,
#StartYear int,
#EndWorkingPeriodId int,
#EndYear int,
#Status int,
#SalariedGuid uniqueidentifier,
#SalariedType int,
#OfficeNumber varchar(64),
#SalariedResultSetId int,
#Keyword nvarchar(2024),
#OperationalUnitIds [dbo].[ListOfID] READONLY
)
AS
DECLARE #AccessibleSalariedGuids [dbo].[ListOfGuid]
IF EXISTS (SELECT * FROM #OperationalUnitIDs)
BEGIN
INSERT INTO #AccessibleSalariedGuids
SELECT FeatureGuid FROM prs_OperationalUnitFeatures
WHERE
OperationalUnitID in (SELECT * FROM #OperationalUnitIDs) AND
FeatureFlag IN (2,4)
END
ELSE BEGIN
INSERT INTO #AccessibleSalariedGuids
SELECT [Guid] FROM ret_vwSalaried
END
SELECT
calcs.[Guid]
FROM
ret_PayrollCalculationCommands command INNER JOIN
ret_PayrollCalculations calcs ON calcs.[CalculationCommandGuid] = command.[Guid] INNER JOIN
ret_vwSalaried salaried ON calcs.[SalariedGuid] = salaried.[Guid]
WHERE
ISNULL(calcs.[MainCalculation],0) = 1 AND
ISNULL(command.[Deleted],0)=0 AND
(#Keyword = '' OR salaried.PersonnelNo = #Keyword OR salaried.FullName LIKE N'%' + #Keyword + '%' OR salaried.FullNameReversed LIKE N'%' + #Keyword + '%') AND
(ISNULL(#calculationCommandType, 0) = 0 OR command.[Type] = #calculationCommandType) AND
(ISNULL(#StartYear, 0) = 0 OR command.[MainYear] >= #StartYear) AND
(ISNULL(#StartWorkingPeriodId, 0) = 0 OR command.[MainWorkingPeriodID] >= #StartWorkingPeriodId) AND
(ISNULL(#EndYear, 0) = 0 OR command.[MainYear] <= #EndYear) AND
(ISNULL(#EndWorkingPeriodId, 0) = 0 OR command.[MainWorkingPeriodID] <= #EndWorkingPeriodId) AND
(ISNULL(#Status, -1) = -1 OR command.[Approved] = #Status) AND
(ISNULL(#SalariedType, -1) = -1 OR salaried.[SalariedType] = #SalariedType) AND
(ISNULL(#SalariedGuid,'00000000-0000-0000-0000-000000000000') = '00000000-0000-0000-0000-000000000000' OR calcs.[SalariedGuid] = #SalariedGuid) AND
(#OfficeNumber IS NULL OR salaried.[OfficeNumber] LIKE '%'+#OfficeNumber+'%') AND
(ISNULL(#SalariedResultSetId, -1) = -1 OR calcs.[SalariedGuid] IN (SELECT [SalariedGuid] FROM ret_SalariedResultSetItems WHERE SalariedResultSetID = #SalariedResultSetId)) AND
(calcs.[SalariedGuid] IN (SELECT * FROM #AccessibleSalariedGuids))
When a bug appears I have to fix the problem in both stored procedures, to avoid duplication I wanted Where clauses in a function and call the function in stored procedures,
But I don't know how?
This is how I would approach this:
If you're using Microsoft sql-server, you can make transact-sql code.
Convert your sql procedure into a string and make the Where clause a text variable that you declare elsewhere.
So it's creating a meta- procedure.
For eg.
DECLARE #whereClause LONGTEXT;
DECLARE #SQLString LONGTEXT;
SET #whereClause = 'i=1'
SET #SQLString = 'SELECT * FROM table WHERE' & #whereClause
sp_executesql SQLString

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

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);

Query optimization. Duplicate subqueries

We found a slow query in our legacy system. What I see in the query is a duplicate fragment. Here's the full query:
DECLARE #SellerId INT;
DECLARE #DateFrom DATETIME;
DECLARE #DateTo DATETIME;
SET #SellerId = 5396884;
SET #DateFrom = '2016-01-05';
SET #DateTo = '2016-10-08';
DECLARE #CurrentDate DATETIME;
SET #CurrentDate = GETDATE();
CREATE TABLE #ReportDate (codes INT, dates DATETIME);
DECLARE #dif as INT;
DECLARE #cont as INT;
DECLARE #currdate as DATETIME;
SET #dif = DATEDIFF(day, #DateFrom, #DateTo);
SET #cont = 1;
SET #currdate = #DateFrom - 1;
WHILE (#cont <= #dif + 1)
BEGIN
SET #currdate = DATEADD(DAY, 1, #currdate);
INSERT INTO #ReportDate VALUES (#cont, #currdate);
SET #cont = #cont + 1;
END
/* HOW TO OPTIMIZE THIS ONE? */
SELECT
#ReportDate.dates as valid_date,
(
SELECT
COUNT(DISTINCT(nonCancelledSales.num_remito)) as actives
FROM
(
SELECT *
FROM salesView
WHERE
salesView.sell_id NOT IN
(
SELECT sell_id
FROM salesStates
WHERE
salesStates.aborted = 1
)
) nonCancelledSales
WHERE
nonCancelledSales.seller_id = #SellerId AND
nonCancelledSales.cancelled = 0 AND
nonCancelledSales.void = 0 AND
nonCancelledSales.hasDiscount = 0 AND
nonCancelledSales.dateOfSale <= #ReportDate.dates AND
nonCancelledSales.currentState = (SELECT MAX(hveest.date)
FROM salesStates hveest
WHERE
hveest.sell_id = nonCancelledSales.sell_id AND
hveest.date <= #ReportDate.dates) AND
nonCancelledSales.lastProductDate = (SELECT MAX(hvepro.date)
FROM productHistory hvepro
WHERE
hvepro.sell_id = nonCancelledSales.sell_id AND
hvepro.date <= #ReportDate.dates)
) total_actives,
(
SELECT
ISNULL(SUM(nonCancelledSales.paymentValue),0) as active
FROM
(
SELECT *
FROM salesView
WHERE
salesView.sell_id NOT IN
(
SELECT sell_id
FROM salesStates
WHERE
salesStates.aborted = 1
)
) nonCancelledSales
WHERE
nonCancelledSales.seller_id = #SellerId AND
nonCancelledSales.cancelled = 0 AND
nonCancelledSales.void = 0 AND
nonCancelledSales.hasDiscount = 0 AND
nonCancelledSales.dateOfSale <= #ReportDate.dates AND
nonCancelledSales.currentState = (SELECT MAX(hveest.date)
FROM salesStates hveest
WHERE
hveest.sell_id = nonCancelledSales.sell_id AND
hveest.date <= #ReportDate.dates) AND
nonCancelledSales.lastProductDate = (SELECT MAX(hvepro.date)
FROM productHistory hvepro
WHERE
hvepro.sell_id = nonCancelledSales.sell_id AND
hvepro.date <= #ReportDate.dates)
) active
FROM
#ReportDate
GROUP BY
#ReportDate.dates
DROP TABLE #ReportDate
Here are the two duplicated fragments I see:
(
SELECT
COUNT(DISTINCT(nonCancelledSales.num_remito)) as actives
FROM
(
SELECT *
FROM salesView
WHERE
salesView.sell_id NOT IN
(
SELECT sell_id
FROM salesStates
WHERE
salesStates.aborted = 1
)
) nonCancelledSales
WHERE
nonCancelledSales.seller_id = #SellerId AND
nonCancelledSales.cancelled = 0 AND
nonCancelledSales.void = 0 AND
nonCancelledSales.hasDiscount = 0 AND
nonCancelledSales.dateOfSale <= #ReportDate.dates AND
nonCancelledSales.currentState = (SELECT MAX(hveest.date)
FROM salesStates hveest
WHERE
hveest.sell_id = nonCancelledSales.sell_id AND
hveest.date <= #ReportDate.dates) AND
nonCancelledSales.lastProductDate = (SELECT MAX(hvepro.date)
FROM productHistory hvepro
WHERE
hvepro.sell_id = nonCancelledSales.sell_id AND
hvepro.date <= #ReportDate.dates)
) total_actives,
(
SELECT
ISNULL(SUM(nonCancelledSales.paymentValue),0) as active
FROM
(
SELECT *
FROM salesView
WHERE
salesView.sell_id NOT IN
(
SELECT sell_id
FROM salesStates
WHERE
salesStates.aborted = 1
)
) nonCancelledSales
WHERE
nonCancelledSales.seller_id = #SellerId AND
nonCancelledSales.cancelled = 0 AND
nonCancelledSales.void = 0 AND
nonCancelledSales.hasDiscount = 0 AND
nonCancelledSales.dateOfSale <= #ReportDate.dates AND
nonCancelledSales.currentState = (SELECT MAX(hveest.date)
FROM salesStates hveest
WHERE
hveest.sell_id = nonCancelledSales.sell_id AND
hveest.date <= #ReportDate.dates) AND
nonCancelledSales.lastProductDate = (SELECT MAX(hvepro.date)
FROM productHistory hvepro
WHERE
hvepro.sell_id = nonCancelledSales.sell_id AND
hvepro.date <= #ReportDate.dates)
) active
Is it fully necessary to duplicate the query ? In the first one he's getting:
COUNT(DISTINCT(nonCancelledSales.num_remito)) as actives
on the second one:
ISNULL(SUM(nonCancelledSales.paymentValue),0) as active
I suppose there has to be some way to rewrite the query but I'm not sure how.
You can combine these, if you use OUTER APPLY.
The idea is:
SELECT . . ., x.actives, x.active
FROM #ReportDate OUTER APPLY
(SELECT COUNT(DISTINCT(nonCancelledSales.num_remito)) as actives,
COALESCE(SUM(nonCancelledSales.paymentValue), 0) as active
. . . -- rest of query here
) x;
In this case, OUTER APPLY is a lot like a correlated subquery in the FROM clause that can return multiple rows.