Extremely ugly query issue - sql-server

If anyone can help me on this I would be very excited...I've already spent about 4 hours and cannot find out why T-SQL gives me wrong results and the same query in sql is fine(I mean only #ZipCodeIDS is not null, that's why I put null for the rest of vars in plain sql).
T-SQL Query:
-- validate the reference number pattern
DECLARE #PCodePattern nvarchar(130)
IF #PCode = '' SET #PCode = NULL
IF #PCode IS NOT NULL
BEGIN
IF LTRIM(RTRIM(#PCode)) <> ''
BEGIN
-- filter by pattern
SELECT #PCodePattern = #PCode
END
END -- #PCode
if (#strAddress is not null)
set #strAddress = '%' + #strAddress + '%'
Declare #listofIDS table(zipcodeids int)
delete from #listofIDS
IF #ZipCodeIDS = '' SET #ZipCodeIDS = NULL
IF #ZipCodeIDS IS NOT NULL
BEGIN
IF CHARINDEX(',', #ZipCodeIDS) = 0
BEGIN
insert #listofIDS values(#ZipCodeIDS)
END
ELSE
BEGIN
set #ZipCodeIDS = #ZipCodeIDS + ','
WHILE CHARINDEX(',', #ZipCodeIDS) <> 0
BEGIN
insert #listofIDS values(Left(#ZipCodeIDS, CHARINDEX(',',#ZipCodeIDS) - 1))
SET #ZipCodeIDS = SUBSTRING(#ZipCodeIDS, CHARINDEX(',',#ZipCodeIDS) + 1, LEN(#ZipCodeIDS) - CHARINDEX(',',#ZipCodeIDS))
END
END
END
-- select the property data
INSERT INTO #PropertyDetails (PropertyID, PCode, PropertyStatusID, PropertyStatusName,
PropertyTypeID, PropertyTypeName, ResearchStatusID,
ResearchStatusName, FullAddress, PartialAddress, Address1,
Address2, ZipCodeID, ZipCode, ZipCodeDescription, CityID,
CityName, StateID, StateName, StateCode, NumBedrooms, NumBathrooms,
LivingSquareFeet, LotSquareFeet, YearBuilt, ZillowLink,
AssessorParcelNumber, DateWentREO, DateAppearedOnMLS, IsOnTheMLS,
ZPropertyID, LowestPrice, HighestPrice, AskingPrice, DateTimeRecorded,
RecordedByPersonID, RecordedByPersonName, AssignedToPersonID,
AssignedToPersonName, WatchTag, Latitude, Longitude)
SELECT p.PropertyID, p.PCode, p.PropertyStatusID, ps.Name, p.PropertyTypeID, pt.Name,
p.ResearchStatusID, rs.Name, dbo.GetAddress(p.PropertyID),
dbo.GetPartialAddress(p.PropertyID), p.Address1, p.Address2, p.ZipCodeID, z.Code,
z.Description, p.CityID, c.Name, p.StateID, s.Name, s.Code, p.NumBedrooms,
p.NumBathrooms, p.LivingSquareFeet, p.LotSquareFeet, p.YearBuilt, p.ZillowLink,
p.AssessorParcelNumber, p.DateWentREO, p.DateAppearedOnMLS, p.IsOnTheMLS,
p.ZPropertyID, p.LowestPrice, p.HighestPrice, p.AskingPrice, p.DateTimeRecorded,
p.RecordedByPersonID, dbo.GetDisplayName(p.RecordedByPersonID), p.AssignedToPersonID,
dbo.GetDisplayName(p.AssignedToPersonID), w.WatchTag, p.latitude, p.longitude
FROM Properties p
JOIN cfgPropertyStatuses ps
ON ps.PropertyStatusID = p.PropertyStatusID
JOIN cfgPropertyTypes pt
ON pt.PropertyTypeID = p.PropertyTypeID
JOIN cfgResearchStatuses rs
ON rs.ResearchStatusID = p.ResearchStatusID
JOIN ZipCodes z
ON z.ZipCodeID = p.ZipCodeID
JOIN cfgStates s
ON s.StateID = p.StateID
LEFT JOIN cfgCities c
ON c.CityID = p.CityID
LEFT JOIN Watches w
ON w.PropertyID = p.PropertyID AND w.PersonID = #LoggedInPersonID
WHERE /*
******* missing filter *******
this line should filter the risks by #LoggedInPersonID via role
******************************
AND */(#PropertyID IS NULL OR p.PropertyID = #PropertyID)
AND (#PCodePattern IS NULL OR p.PCode LIKE #PCodePattern)
AND (#ZipCodeIDS IS NULL
OR p.ZipCodeID IN (select zipcodeids from #listofIDS))
AND (#NumBedroomsFrom IS NULL OR (p.NumBedrooms >= #NumBedroomsFrom
AND #NumBedroomsTo IS NOT NULL
AND p.NumBedrooms <= #NumBedroomsTo)
OR (p.NumBedrooms = #NumBedroomsFrom
AND #NumBedroomsTo IS NULL))
AND (#NumBedroomsTo IS NULL OR (p.NumBedrooms <= #NumBedroomsTo
AND (#NumBedroomsTo IS NULL OR p.NumBedrooms <= #NumBedroomsTo)))
AND (#LivingSizeFrom IS NULL OR (p.LivingSquareFeet >= #LivingSizeFrom))
AND (#LivingSizeTo IS NULL OR (p.LivingSquareFeet <= #LivingSizeTo))
AND (#LotSizeFrom IS NULL OR (p.LotSquareFeet >= #LotSizeFrom))
AND (#LotSizeTo IS NULL OR (p.LotSquareFeet <= #LotSizeTo))
AND
/* if status is null, return all. Or, return only statuses that are passed in */
(#PropertyStatuses IS NULL or
((p.PropertyStatusID=#PropertyStatuses and (p.PropertyStatusID & (32 | 128)) = 0) or
#PropertyID is not null or #PCode is not null) or
(p.PropertyStatusID = (p.PropertyStatusID & #PropertyStatuses)))
/*
-- return the property if the specific ID was given otherwise ommit Sold and Archived
AND ((p.PropertyStatusID & (32 /*sold*/ | 128 /*archived*/)) = 0
OR #PropertyID IS NOT NULL
OR #PCode IS NOT NULL))
OR (p.PropertyStatusID = (p.PropertyStatusID & #PropertyStatuses)))
*/
AND (#PropertyTypes IS NULL
OR (p.PropertyTypeID = (p.PropertyTypeID & #PropertyTypes)))
AND (#ResearchStatuses IS NULL
OR (p.ResearchStatusID = (p.ResearchStatusID & #ResearchStatuses)))
AND (#IsOnTheMLS IS NULL OR p.IsOnTheMLS = #IsOnTheMLS)
and (#strAddress is null or (p.Address1 LIKE #strAddress or p.Address2 LIKE #strAddress))
RETURN
and the same, translated by me in SQL (which works good):
/****** Script for SelectTopNRows command from SSMS ******/
SELECT TOP 1000 [PropertyID]
,[PCode]
,[Address1]
,[Address2]
,[NumBedrooms]
,[NumBathrooms]
,[LivingSquareFeet]
,[LotSquareFeet]
,[YearBuilt]
,[ZillowLink]
,[AssessorParcelNumber]
,[DateWentREO]
,[DateAppearedOnMLS]
,[IsOnTheMLS]
,[ZPropertyID]
,[LowestPrice]
,[HighestPrice]
,[AskingPrice]
,[DateTimeRecorded]
,[RecordedByPersonID]
,[AssignedToPersonID]
,[latitude]
,[longitude]
,[Zestimate]
FROM [dev_hotsheetDB].[dbo].[Properties] p
JOIN [dev_hotsheetDB].[dbo].cfgPropertyStatuses ps
ON ps.PropertyStatusID = p.PropertyStatusID
JOIN [dev_hotsheetDB].[dbo].cfgPropertyTypes pt
ON pt.PropertyTypeID = p.PropertyTypeID
JOIN [dev_hotsheetDB].[dbo].cfgResearchStatuses rs
ON rs.ResearchStatusID = p.ResearchStatusID
JOIN [dev_hotsheetDB].[dbo].ZipCodes z
ON z.ZipCodeID = p.ZipCodeID
JOIN [dev_hotsheetDB].[dbo].cfgStates s
ON s.StateID = p.StateID
LEFT JOIN [dev_hotsheetDB].[dbo].cfgCities c
ON c.CityID = p.CityID
where
(NULL IS NULL OR p.PropertyID = NULL)
AND (NULL IS NULL OR p.PCode LIKE NULL)
AND ('1' IS NULL
OR p.ZipCodeID IN (select zipcodeids from [dev_hotsheetDB].[dbo].[listofIDS]))
AND (NULL IS NULL OR (p.NumBedrooms >= NULL
AND NULL IS NOT NULL
AND p.NumBedrooms <= NULL)
OR (p.NumBedrooms = NULL
AND NULL IS NULL))
AND (NULL IS NULL OR (p.NumBedrooms <= NULL
AND (NULL IS NULL OR p.NumBedrooms <= NULL)))
AND (NULL IS NULL OR (p.LivingSquareFeet >= NULL))
AND (NULL IS NULL OR (p.LivingSquareFeet <= NULL))
AND (NULL IS NULL OR (p.LotSquareFeet >= NULL))
AND (NULL IS NULL OR (p.LotSquareFeet <= NULL))
AND
/* if status is null, return all. Or, return only statuses that are passed in */
(NULL IS NULL or
((p.PropertyStatusID=NULL and (p.PropertyStatusID & (32 | 128)) = 0) or
NULL is not null or NULL is not null) or
(p.PropertyStatusID = (p.PropertyStatusID & NULL)))
/*
-- return the property if the specific ID was given otherwise ommit Sold and Archived
AND ((p.PropertyStatusID & (32 /*sold*/ | 128 /*archived*/)) = 0
OR #PropertyID IS NOT NULL
OR #PCode IS NOT NULL))
OR (p.PropertyStatusID = (p.PropertyStatusID & #PropertyStatuses)))
*/
AND (NULL IS NULL
OR (p.PropertyTypeID = (p.PropertyTypeID & NULL)))
AND (NULL IS NULL
OR (p.ResearchStatusID = (p.ResearchStatusID & NULL)))
AND (NULL IS NULL OR p.IsOnTheMLS = NULL)
and (NULL is null or (p.Address1 LIKE NULL or p.Address2 LIKE NULL))
Please note that the issue is only related to IN statement... When #ZipCodeIDS = '1,2,3' it should return 414 results (plain sql ok) but T-SQL function returns 80..
The strange thing I've noticed is that T-SQL only takes in consideration FIRST id from #ZipCodeIDS (as you see I split these ids and put them into a temp table). So here's the issue - about this first id... (cannot confirm that this is the only issue, because there were times when for the first zipCodeId it shouldn't return anything but it still returned results)
Can you give a helping hand please?
Ps: for my plain sql query, I've used a real table with those ids, just to mimic the behavior as much as possible...
UPDATE: The splitting of the #ZipCodeIDS and insertion into the temp table works perfectly: https://data.stackexchange.com/stackoverflow/q/109406/

Solved the issue with Timbo help!!!!!
I've declared #ZipCodeIDS varchar and somehow it is made by default VARCHAR(1).
I changed it to #ZipCodeIDS varchar(50) and not it perfectly works!!!!
Sorry guys because this declaration was hidden from you!

Related

Multiple conditions on a where clause column in SQL Server

I had written a stored procedure where it needs to execute the where condition based on the parameter values as follows :
alter proc sp_cc_get_grn_details
(
#vendor_id varchar(100) = null,
#po_id int = null,
#invoice_id int = null,
#invoice_from_dt datetime2 = null,
#invoice_to_dt datetime2 = null,
#grn_status int = null
)
AS
BEGIN
SELECT vd.vendor_id,vd.vendor_name,id.po_id,id.invoice_id,id.invoice_amount,id.invoice_date,
CASE
WHEN id.grn_status = 0 THEN 'Pending'
WHEN id.grn_status = 1 THEN 'Completed'
ELSE 'Pending'
END AS grn_status into #Tempres
FROM
vendor_details vd JOIN po_details pd on vd.vendor_id = pd.vendor_id
join invoice_details id on id.po_id = pd.po_id
WHERE
(#vendor_id is null or #vendor_id = '' or vd.vendor_id = #vendor_id) AND
(#po_id is null or #po_id = '' or id.po_id = #po_id) AND
(#invoice_id is null or #invoice_id = '' or id.invoice_id = #invoice_id) and
(id.invoice_date BETWEEN #invoice_from_dt AND #invoice_to_dt)
if(#grn_status = 1)
select * from #Tempres where grn_status = 'Completed';
else if(#grn_status = 2)
select * from #Tempres where grn_status = 'Pending';
else
select * from #Tempres;
drop table #Tempres;
END
The above procedure is working. But what's my need is, Is there any way to make "#grn_status" parameter too in the where clause instead of writing with if & else.
something like this would work
where #grn_Status not in (1, 2) or
grn_status =
case #grn_status
when 1 then 'Completed'
when 2 then 'Pending'
end

SQL Server - WHERE clause with CASE

ALTER PROCEDURE GetVendor_RMA_CreditMemo
(#HasCreditMemoNo INT)
BEGIN
SELECT
*
FROM
(SELECT
CreditMemoNumber,
CASE WHEN CreditMemoNumber != ''
THEN 1
ELSE 0
END AS HasCreditMemoNo
FROM
XYZ) as C
WHERE
(C.HasCreditMemoNo = #HasCreditMemoNo OR #HasCreditMemoNo = -1)
END
CreditMemoNumber is a varchar column
I want to achieve this:
CASE
WHEN #HasCreditMemoNo = 0
THEN -- select all rows with no value in CreditMemoNumber Column,
WHEN #HasCreditMemoNo = 1
THEN -- all rows that has some data,
WHEN #HasCreditMemoNo = -1
THEN -- everything regardless..
You can't do this kind of thing with a CASE.
The correct way to do it is with OR:
WHERE (#HasCreditMemoNo = 0 AND {no value in CreditMemoNumber Column})
OR
(#HasCreditMemoNo = 1 AND {all rows that has some data})
OR
(#HasCreditMemoNo = -1)
Would this work for you? I'm not sure if it would improve your performance. You may be better off writing an if else if else statement and three separate select statements with an index on the CreditMemoNumber column.
ALTER PROCEDURE GetVendor_RMA_CreditMemo(#HasCreditMemoNo int)
BEGIN
select
CreditMemoNumber,
case when CreditMemoNumber != '' then 1 else 0 end as HasCreditMemoNo
from XYZ
where
(#HasCreditMemoNo = 0 and (CreditMemoNumber is null or CreditMemoNumber = ''))
or (#HasCreditMemoNo = 1 and CreditMemoNumber != '')
or (#HasCreditMemoNo = -1)
END

UPDATE in SQL Server 2008 getting '0 rows affected'

I've changed this query numerous times but still see '0 rows affected. Everything works in SELECT statement but fails in the UPDATE.
Here is the query:
UPDATE tblVisitLog
SET tblVisitLog.TimeOUT = (SELECT CAST(SUBSTRING(tblScheduleData.E_Time, 1,2 ) + ':' + SUBSTRING(tblScheduleData.E_Time, 3,2) + ':00.000' AS datetime)
FROM tblScheduleData
WHERE tblVisitLog.Encounter_code = tblScheduleData.Encounter_code),
tblVisitLog.Provider = (SELECT Provider
FROM tblScheduleData s
WHERE tblVisitLog.Encounter_code = s.Encounter_code),
tblVisitLog.recStatus = 0,
tblVisitLog.Printed = N'N'
WHERE
tblVisitLog.TimeOUT IS NULL
AND tblVisitLog.Provider IS NULL
The datatypes are:
Encounter_code (int, null)
TimeOUT (datetime, null)
Provider (nvarchar(50), null)
recStatus (smallint, not null)
Printed (nvarchar(50), null)
The values that I'm updating are all NULL, the values I'm pulling in from tblScheduleData.E_Time are varchar(4), null and formatted like '1045'.
Your update statement would be a LOT cleaner using a join here. Something like this.
UPDATE vl
SET TimeOUT = CAST(SUBSTRING(s.E_Time, 1,2 )+ ':' + SUBSTRING(s.E_Time, 3,2) + ':00.000' AS datetime)
, Provider = s.Provider
, recStatus = 0
, Printed = N'N'
from tblVisitLog vl
join tblScheduleData s on vl.Encounter_code = s.Encounter_code
WHERE vl.TimeOUT Is NULL
AND vl.Provider Is Null
The message it's pretty clear '0 rows affected'
So try do this query and you will see an empty result
select * from tblVisitLog
WHERE TimeOUT Is NULL AND Provider Is Null
First change the criteria

sql stored procedure - i would like to change it to a job but it has parameters

I have a VERY long running, heavy stored procedure, so I would like to change it over to a job that runs every night and updates a table so the user can run it quickly during the day. My problem is that it takes parameters IN THE LEFT JOIN, so I don't see how I could do it. I tried to remove the parameters from the joins and just take all the records, but first problem with that is that these left joins are joins to table valued functions with group by clauses (so it's tons of records now) and also when I did it, it crashed my whole server. I will post part of my stored proc to give you an idea of what i'm doing for now.
--alternatively, i would take an answer that could change my query perfomance from 2 minutes to 10 seconds. :)
--btw, another thing that is slowing down this query is that the functions are querying a linked server...
create PROC [dbo].[mySP]
#FromDate DateTime,
#ToDate DateTime = NULL,
#Style NVARCHAR(max),
#ItemType NVARCHAR(300),
#ItemCode NVARCHAR(150)= null,
#ItemsNotSold INT,
#MultiplyUsage DECIMAL(18,4),
#SParts BIT,
#vendorId nvarchar(50),
#currentPage int,
#largeOrderSoNumbers nvarchar(300) = null,
#excludeprojTag BIT,
#hasOrderQty BIT = null,
#createPO BIT = null,
#excludeTestOrders BIT = null,
#refresh BIT = null,
#userid int = null,
#positiveOverUse BIT = null
AS
SELECT #FROMDATE = #FROMDATE
,#ToDate=#ToDate
,#Style=#Style
,#ItemType=#ItemType
,#ItemCode=#ItemCode
,#ItemsNotSold=#ItemsNotSold
,#MultiplyUsage=#MultiplyUsage
,#SParts=#SParts
,#vendorId=#vendorId
,#currentPage=#currentPage
,#largeOrderSoNumbers=#largeOrderSoNumbers
,#excludeprojTag=#excludeprojTag
,#hasOrderQty =#hasOrderQty
,#createPO =#createPO
,#excludeTestOrders =#excludeTestOrders
,#refresh =#refresh
,#userid =#userid
,#positiveOverUse=#positiveOverUse
DECLARE #amountPerPage int = 400;
DECLARE #startingPoint int = (#currentpage - 1) * #amountPerPage
SET #TODATE = NULLIF(#TODATE,'1/1/4000');
SET #ITEMCODE = NULLIF(#ITEMCODE,'');
SET #largeOrderSoNumbers = NULLIF(#LARGEORDERSONUMBERS,'');
BEGIN
IF #Style = '-1'
SET #Style = NULL
IF #ItemType = '-1'
SET #ItemType = NULL
END
SELECT
ISNULL(c.NewQB_ListID,iit.ListID) ListID,
(select salesdesc from iteminventory i where i.listid = ISNULL(c.NewQB_ListID,iit.ListID)) as SalesDesc,
isnull(inl.linename,'') + isnull(c.NewName,Name) as ItemCode ,
max(il.CubicMeterKD) as CubicMeterKD,
sum(CONVERT(decimal(18,4),inl.Quantity) )
- sum(CONVERT(decimal(18,4),inl.qtyRuleTag))
+ CONVERT(decimal(18,4),isnull(ai.qty,0))
-CONVERT(decimal(18,4),isnull(ai.QtyRuleTag,0))
AS TotalQtyUesd,
sum(convert(decimal(18,4),isnull(inl.QtyRuleTag,0)))
as QtyUsedWithProjectTag,
Convert(decimal(18,4),QuantityOnHand) as OnHand,
CONVERT(int,ISNULL(EzQtyOnSO.Qty,0)) as OnSalesOrder,
CONVERT(int,ISNULL(EzQtyAnyStatus.QtyLgO,0))as OnLgOrder,
Convert(decimal(18,4),QuantityOnOrder) as OnPO,
Convert(decimal(18,4),isnull(LargePO.lgOrderQtyOnPO,0)) as lgOrderQtyOnPO ,
fl.LineName
INTO #Q
FROM
iteminventory iit
LEFT JOIN Lines fl
ON iit.ParentRef_ListID = QB_LisiID
LEFT JOIN tb_ItemList il
ON iit.ListID = il.QBListID
LEFT JOIN InlSales(#FromDate,#ToDate, #excludeprojtag, #excludeTestOrders) INL
ON IIT.LISTID = INL.ITEMREF_LISTID
LEFT JOIN tb_CombinedItems c
ON iit.ListID = c.ListID
LEFT JOIN [QuantityInvoice](#FromDate, #ToDate,#excludeprojTag,#excludeTestOrders) as ai
ON ai.QBID = iit.ListID
LEFT JOIN fn_QuantityOnSalesOrder(#excludeTestOrders) AS EzQtyOnSO
ON iit.ListID = EzQtyOnSO.QBID
LEFT JOIN QuantityAnyStatus(#largeOrderSoNumbers, #excludeprojTag) AS EzQtyAnyStatus
ON iit.ListID = EzQtyAnyStatus.QBID
LEFT JOIN dbo.[FN_LargePO](#excludeTestOrders) LargePO --WITH (nolock)
ON LargePO.QBID = iit.ListID
WHERE
(#Style is null or ISNULL(c.ParentListID,ParentRef_ListID) in (SELECT Value From fn_MultiValueParameter(#Style))) AND
(#ItemType is null or ItemTypeCode in (SELECT Value From fn_MultiValueParameter(#ItemType))) AND
(#ItemCode is null or il.ItemCode like '%' + #ItemCode + '%') AND
(IsActive = 1 OR c.ListID IS NOT NULL)
GROUP BY
ISNULL(c.NewQB_ListID,iit.ListID),
ISNULL(c.NewName,Name),
inl.LineName,
QuantityOnHand,
iit.QuantityOnOrder,
CONVERT(int,ISNULL(EzQtyOnSO.Qty,0)),
fl.LineName,
CONVERT(decimal(18,4),isnull(ai.qty,0)),
Convert(decimal(18,4),isnull(LargePO.lgOrderQtyOnPO,0)),
CONVERT(int,ISNULL(EzQtyAnyStatus.QtyLgO,0)),
CONVERT(decimal(18,4),isnull(ai.QtyRuleTag,0))
IF #ItemsNotSold = 1
BEGIN
DELETE FROM #Q
WHERE isnull(TotalQtyUesd,0) <> 0
END
IF #ItemsNotSold = 2
BEGIN
DELETE FROM #Q
WHERE isnull(TotalQtyUesd,0) = 0
END
SELECT
q.ListID,
q.SalesDesc,
q.ItemCode,
MAX(isnull(q.CubicMeterKD,0)) as CubicMeterKD,
SUM(q.TotalQtyUesd)
TotalQtyUesd,
SUM(q.QtyUsedWithProjectTag) as QtyUsedWithProjectTag,
SUM(q.OnHand) OnHand,
SUM(q.OnSalesOrder) OnSalesOrder,
SUM(q.OnLgOrder) OnLgOrder,
SUM(q.OnPO)
- isnull(SUM(q.lgOrderQtyOnPO),0)
OnPO,
SUM(q.lgOrderQtyOnPO) as lgOrderQtyOnPO,
LineName
INTO #QTY
FROM
#Q q
GROUP BY
q.ListID,
q.salesdesc,
q.ItemCode,
q.LineName
;WITH Results AS
(
SELECT
isnull(P.listid,'') as ListID,
isnull(P.SalesDesc,'') as SalesDesc,
isnull(P.itemcode,'') as ItemCode,
ISNULL(CubicMeterKD,0) AS CubicMeterKD,
isnull(TotalQtyUesd,0) as TotalQtyUsed,
isnull(QtyUsedWithProjectTag,0) as QtyUsedWithProjectTag,
isnull(onhand,0) as OnHand,
isnull((OnHand - OnSalesOrder - OnLgOrder),0) as available,
isnull(OnLgOrder,0) as OnLgOrder,
isnull(OnPO,0) as OnPo,
isnull(lgOrderQtyOnPO,0) as lgOrderQtyOnPO,
isnull(((OnHand - OnSalesOrder) + OnPO) ,0) AS [AvailableAndOnPo],
isnull((TotalQtyUesd * #MultiplyUsage) - ((OnHand - OnSalesOrder) + OnPO),0) AS [AvlOnPOminusUsed],
isnull((((TotalQtyUesd * #MultiplyUsage) - ((OnHand - OnSalesOrder) + OnPO)) / CASE WHEN TotalQtyUesd > 0 THEN TotalQtyUesd END)*100,0) AS PctOver
,isnull(linename,0) as LineName,
isnull((select price from qbdb.dbo.tb_iteminfodetail where vendorlistid = #vendorid and itemcode =isnull(P.itemcode,'')),0.0) as price
,isnull(pod.qtytoReOrder,0) as qtyToReOrder
,isnull(pod.qtytoOrder,0) as qtyToOrder
,isnull(pod.includePO,0) as includePO
,ROW_NUMBER() OVER (ORDER BY ITEMCODE) AS RowNum
FROM #qty AS p
left join dbo.purchaseorderpreliminarydetails pod on pod.listid = P.listid and pod.deleteFlag = 0
and headerid = (select top 1 headerid from purchaseorderpreliminary where deleteFlag = 0)
WHERE
CASE WHEN #positiveOverUse = 1 THEN
isnull((((TotalQtyUesd * #MultiplyUsage) - ((OnHand - OnSalesOrder) + OnPO)) / CASE WHEN TotalQtyUesd > 0 THEN TotalQtyUesd END)*100,0)
ELSE 1 END >0
AND
case when #hasOrderQty = 1 then isnull(pod.QtyToReOrder,0) else 1 end > 0
and
CASE WHEN #SPARTS = 1 THEN CASE WHEN
ItemCode IN (
'APP',
'CD',
'-S',
'L0',
'L/42',
'L01',
'Lfrgs2',
'Lfad2',
'Sfasdf9',
'SdafdsA',
'Sfasdf3',
'Sasdf6',
'asdf0',
'Sf6',
'fasdfadf2',
'fasdfasdf',
'S2236',
'S12342',
'Sdf 30',
'SdfE 36',
'fgsfgs',
'fasdf-fdasf',
'fadf',
'fasdf-fasdf',
'sdaf',
'adf 11"',
'fda 14"',
'fdas 24"') THEN 1 ELSE 0 END ELSE 1 END = 1
)
SELECT (select count(rownum) from results) as totalItems,* FROM Results WHERE
rownum between #startingPoint + 1 and #startingPoint + #amountPerPage
Have a form the users can put their parameters into before they go home, and save them into a new table in the database. Change the stored procedure to either get the parameters from this new table or to use the new table in the joins &c. The SP now doesn't need the parameters to sent to it. Finally call the SP via a Job.

SQL Server - How to make an INTERSECT select optional?

I'm working on an advanced search sproc and would like to know if it is possible for a portion of my select to be included or not based on a parameter. I could use an IF ELSE on my parameter, but I already have one for another parameter, and that seems like a lot of code duplication.
-- My advanced search function allows a user to specify various parameters. The basic search can be EXACT or not (contains vs freetext - first if), and other parameters (AND) can be specified. Specific keywords can also be selected as well (intersect).
My issue is that when #Keywords is null, I don't want to include the final INTERSECT SELECT ... portion of the code at the bottom of my example. Is there a quick way to do this without adding another IF ELSE in the top and bottom queries? Let me know if you need more detailed information.
declare #SearchTerms nvarchar(4000)
declare #GalleryId int
declare #Keywords nvarchar(4000)
declare #ExactWord int
declare #BeginDateUpload datetime
declare #EndDateUpload datetime
declare #BeginDateTaken datetime
declare #EndDateTaken datetime
declare #MinFileSize int
declare #MaxFileSize int
declare #AlbumType bit
declare #ImageType int
declare #AudioType int
declare #OtherType int
declare #VideoType int
set #SearchTerms = 'tulips'
set #GalleryId = 1
set #Keywords = null -- 'st-jean'
set #ExactWord = null
set #BeginDateUpload = null
set #EndDateUpload = null
set #BeginDateTaken = null
set #EndDateTaken = null
set #MinFileSize = null
set #MaxFileSize = null
set #AlbumType = 1
set #ImageType = 1
set #AudioType = 1
set #OtherType = 1
set #VideoType = 1
IF ISNULL(#ExactWord, 0) = 1
BEGIN
[... snip ...]
END
ELSE
select t1.* from (
SELECT 'm' as objType, m.MediaObjectId
FROM gs_mediaObjectMetadata md
INNER JOIN dbo.[gs_MediaObject] m
ON md.FKMediaObjectId = m.MediaObjectId
INNER JOIN dbo.[gs_Album] a
ON a.AlbumId = m.FKAlbumId
WHERE FREETEXT (value, #SearchTerms)
AND a.FKGalleryId = #GalleryId
AND (m.DateAdded >= ISNULL(#BeginDateUpload, m.DateAdded))
AND (m.DateAdded <= ISNULL(#EndDateUpload, m.DateAdded))
AND (m.DateTaken is NULL OR m.DateTaken >= ISNULL(#BeginDateTaken, m.DateTaken))
AND (m.DateTaken is NULL OR m.DateTaken <= ISNULL(#EndDateTaken, m.DateTaken))
AND (m.OriginalSizeKB >= ISNULL(#MinFileSize, m.OriginalSizeKB))
AND (m.OriginalSizeKB <= ISNULL(#MaxFileSize, m.OriginalSizeKB))
AND((m.FKMediaObjectTypeId = ISNULL(#ImageType, 0))
OR (m.FKMediaObjectTypeId = ISNULL(#AudioType, 0))
OR (m.FKMediaObjectTypeId = ISNULL(#VideoType, 0))
OR (m.FKMediaObjectTypeId = ISNULL(#OtherType, 0)))
union
SELECT 'm' as objType, m.MediaObjectId
FROM dbo.[gs_MediaObject] m
INNER JOIN dbo.[gs_Album] a
ON a.AlbumId = m.FKAlbumId
WHERE FREETEXT ((m.Title, OriginalFilename), #SearchTerms)
AND a.FKGalleryId = #GalleryId
AND (m.DateAdded >= ISNULL(#BeginDateUpload, m.DateAdded))
AND (m.DateAdded <= ISNULL(#EndDateUpload, m.DateAdded))
AND (m.DateTaken is NULL OR m.DateTaken >= ISNULL(#BeginDateTaken, m.DateTaken))
AND (m.DateTaken is NULL OR m.DateTaken <= ISNULL(#EndDateTaken, m.DateTaken))
AND (m.OriginalSizeKB >= ISNULL(#MinFileSize, m.OriginalSizeKB))
AND (m.OriginalSizeKB <= ISNULL(#MaxFileSize, m.OriginalSizeKB))
AND((m.FKMediaObjectTypeId = ISNULL(#ImageType, 0))
OR (m.FKMediaObjectTypeId = ISNULL(#AudioType, 0))
OR (m.FKMediaObjectTypeId = ISNULL(#VideoType, 0))
OR (m.FKMediaObjectTypeId = ISNULL(#OtherType, 0)))
) t1
--IF #Keywords != null -- conditional intersect
intersect
SELECT 'm' as objType, m.MediaObjectId
FROM dbo.[gs_MediaObject] m
INNER JOIN dbo.[gs_Album] a
ON a.AlbumId = m.FKAlbumId
left join dbo.gs_MediaObjectMetadata md
on m.MediaObjectId = md.FKMediaObjectId
WHERE FREETEXT ((m.Title, OriginalFilename), #SearchTerms)
AND a.FKGalleryId = #GalleryId
AND (m.DateAdded >= ISNULL(#BeginDateUpload, m.DateAdded))
AND (m.DateAdded <= ISNULL(#EndDateUpload, m.DateAdded))
AND (m.DateTaken is NULL OR m.DateTaken >= ISNULL(#BeginDateTaken, m.DateTaken))
AND (m.DateTaken is NULL OR m.DateTaken <= ISNULL(#EndDateTaken, m.DateTaken))
AND (m.OriginalSizeKB >= ISNULL(#MinFileSize, m.OriginalSizeKB))
AND (m.OriginalSizeKB <= ISNULL(#MaxFileSize, m.OriginalSizeKB))
AND((m.FKMediaObjectTypeId = ISNULL(#ImageType, 0))
OR (m.FKMediaObjectTypeId = ISNULL(#AudioType, 0))
OR (m.FKMediaObjectTypeId = ISNULL(#VideoType, 0))
OR (m.FKMediaObjectTypeId = ISNULL(#OtherType, 0)))
and UPPER(md.Description) = 'KEYWORDS'
and exists (
SELECT *
FROM dbo.fnSplit(Replace(md.Value, '''', ''''''), ',') split
WHERE split.item in
(SELECT * from dbo.fnSplit(Replace(#Keywords, '''', ''''''), ','))
)
Thank you
What about instead of doing the intersect, try this out in your inner queries : #Keyword is null or .....
and ( #Keywords is null or (UPPER(md.Description) = 'KEYWORDS'
and exists (
SELECT *
FROM dbo.fnSplit(Replace(md.Value, '''', ''''''), ',') split
WHERE split.item in
(SELECT * from dbo.fnSplit(Replace(#Keywords, '''', ''''''), ','))
)
)
)

Resources