I am working on a Stored Procedure that has two input parameters that I need to use COLLATE SQL_Latin1_General_CP1_CI_AS so that I can query non-case sensitive results; however, I would also like to allow for a Show All Option with the inputs. I have not found a way for the Collate to work in a case statement. Note: As a work around I will code with 4 different If statements for the different scenarios of choosing a value and/or show all, but would like something cleaner if possible. Current Code below
Declare
#INCo as bCompany,
#MatBeg as bMatl,
#MatEnd as bMatl,
#Catg as bGroup,
#Model as VarChar(20),
#PatternM as VarChar(20),
#SellOn as VarChar(20),
#PatternS as VarChar(20),
#ShowZero as bYN
set #INCo = '1'
set #MatBeg = '0'
set #MatEnd = 'ZZZZZZZZZZ'
set #Catg = '0'
set #Model = '637'
set #SellOn = 'EBAY'
set #ShowZero = 'Y'
begin
set #PatternM = '%' + #Model + '%';
set #PatternS = '%' + #SellOn + '%';
select i.INCo, i.Material, h.Description, h.Category, c.Description as CatgDesc, i.Booked as Quantity, i.PhyLoc, p.Storage,
i.udModelFit as FitsModel, i.udSellPriceNew as LikeNewSellPrice, i.udSellPriceUsed as UsedSellPrice, i.udSellingOn as SellingOn
from INMT i
left outer join HQMT h on i.MatlGroup=h.MatlGroup and i.Material=h.Material
left outer join HQMC c on h.MatlGroup=c.MatlGroup and h.Category=c.Category
left outer join udPhysicalloc p on i.PhyLoc=p.Physicalloc
where i.INCo = (CASE when #INCo <> 0 then #INCo else i.INCo END)
and i.Material >= #MatBeg and i.Material <= #MatEnd
and c.Category = (CASE when #Catg <> 0 then #Catg else c.Category END)
and i.udModelFit COLLATE SQL_Latin1_General_CP1_CI_AS like #PatternM
and i.udSellingOn COLLATE SQL_Latin1_General_CP1_CI_AS like #PatternS
and i.Booked >= (CASE when #ShowZero = 'N' then 1 else 0 END)
END
This code works works great if I only care about having non-case sensitive results for #Model and #SellOn. However, like the other parameters I have, I would like to include something that allows to show all results for that parameter. Something like:
i.udModelFit = (CASE when #Model <> 'ALL' then COLLATE SQL_Latin1_General_CP1_CI_AS like #PatternM else i.udModelFit END)
So as an example I would like to input #Model = 'ALL' and #SellOn = 'eBay' and results would be any Model with Sell On = EBAY (non-case sensitive)
Update: I was able to modify Where to the following and I am getting the desired results now.
where i.INCo = (CASE when #INCo <> 0 then #INCo else i.INCo END)
and i.Material >= #MatBeg and i.Material <= #MatEnd
and c.Category = (CASE when #Catg <> 0 then #Catg else c.Category END)
and (
(#Model IS NULL or i.udModelFit COLLATE SQL_Latin1_General_CP1_CI_AS like #PatternM)
or ((i.udModelFit like '%' or i.udModelFit IS NULL) and #Model = 'ALL')
)
and (
(#SellOn IS NULL or i.udSellingOn COLLATE SQL_Latin1_General_CP1_CI_AS like #PatternS)
or ((i.udSellingOn like '%' or i.udSellingOn IS NULL) and #SellOn = 'ALL')
)
and i.Booked >= (CASE when #ShowZero = 'N' then 1 else 0 END)
You can use and( (...) or (...) ) e.g.
and (#Model = 'ALL' or i.udModelFit like #PatternM SQL_Latin1_General_CP1_CI_AS)
If you want to toggle different search options based on input, you may want to consider writing your procedure using dynamic sql, and/or adding option (recompile).
Catch-all query reference:
Parameter Sniffing, Embedding, and the RECOMPILE Options - Paul White
Dynamic Search Conditions - Erland Sommarskog
Catch-all queries - Gail Shaw
An Updated "Kitchen Sink" Example - Aaron Bertand
Related
I'm trying to run a somewhat complex sql statement using the 'group_concat' function for statistics.
When I run the sql statement using navicat, the correct result is returned.But when I use mybatis debug this sql in idea, it returns null value.
I use HashMapHashMap<String,Long> to receive the result set executed by mybatis,
I guess the result set returned by mybatis executing sql is wrongly encapsulated.
But I tried for a long time and couldn't find a solution.
I can't post pictures here,I display the results in a table.
cha
hege
lianghao
youxiu
1
1
2
1
Receive declaration at the mapper layer
HashMap<String, Long> getOption(#Param("column") String column);
Here is the sql code:
<select id="getOption" resultType="java.util.HashMap">
SELECT GROUP_CONCAT(form.cha SEPARATOR '') cha,
GROUP_CONCAT(form.hege SEPARATOR '') hege,
GROUP_CONCAT(form.lianghao SEPARATOR '') lianghao,
GROUP_CONCAT(form.youxiu SEPARATOR '') youxiu
FROM (
SELECT
( CASE WHEN #{column} = '0' THEN count(*) ELSE NULL END) AS 'cha',
( CASE WHEN #{column} = '1' THEN count(*) ELSE NULL END ) AS 'hege',
( CASE WHEN #{column} = '2' THEN count(*) ELSE NULL END ) AS 'lianghao',
( CASE WHEN #{column} = '3' THEN count(*) ELSE NULL END ) AS 'youxiu'
FROM corp_feedback_student
GROUP BY #{column}
) form
</select>
Thanks everyone for helping me!!
I am searching for a way to make the sql statement declare a AS example as Yes when the value is greater than 0 and No if 0 after I count the result while retreiving the data from the database.
This (is not working) is what I tried so far. I hope my tryout is making sence. I first make a select count on planning_clientid the result is 0 or more. If the result is 0 I need timesonplanning (perhaps change that name after its working) to be No and if higher than Yes. So in steady of the count result I need Yes or No, Is this possible?
Part that is not working:
(CASE WHEN(SELECT COUNT(planning_clientid) FROM tbl_planning WHERE planning_afgehandeld = 0 AND a.client_id = planning_clientid)> 0 THEN 'Yes' ELSE 'No' END AS timesonplanning
The whole statement:
SELECT a.*, own1.naam AS resposible_btw, own2.naam AS resposible_client, (CASE WHEN(SELECT COUNT(planning_clientid) FROM tbl_planning WHERE planning_afgehandeld = 0 AND a.client_id = planning_clientid)> 0 THEN 'Yes' ELSE 'No' END AS timesonplanning FROM tbl_clients a LEFT JOIN gebruikers own1 ON own1.id = a.client_ownerob LEFT JOIN gebruikers own2 ON own2.id = a.client_owner
Desired result:
timesonplanning Yes (when count if higher than 0)
timesonplanning No (when count is 0)
The error you indicated in the comments indicates a syntax error (albeit in Dutch). This is indeed to be expected as the query you included doesn’t close the initial parenthesis character ( you used right before your CASE keyword.
Resolve this by removing the initial parenthesis before CASE (as it doesn’t seem particularly necessary in this context), or properly close it by inserting a close parenthesis ) after the END keyword:
SELECT a.*, own1.naam AS resposible_btw, own2.naam AS resposible_client, (CASE WHEN(SELECT COUNT(planning_clientid) FROM tbl_planning WHERE planning_afgehandeld = 0 AND a.client_id = planning_clientid)> 0 THEN 'Yes' ELSE 'No' END) AS timesonplanning FROM tbl_clients a LEFT JOIN gebruikers own1 ON own1.id = a.client_ownerob LEFT JOIN gebruikers own2 ON own2.id = a.client_owner
I have a stored procedure for search screen where I have 5 different filters.
Users can leave the filters empty or have one filter and click on search button.
All the data is coming from database, I am trying to create stored procedure which can exclude columns in where clause if the parameter value is empty string.
#Id as nvarchar(256) = 1
#blnIsinProgress bit = 0
#strStatus varchar(20) = ''
#strName varchar(50) = ''
#strConfirmationNumber varchar(50) = 123
#dtmSubmittedFrom Date = '12/31/9999'
#dtmSubmittedTo Date = '12/31/9999'
as
BEGIN
SELECT *
FROM tblTable
WHERE
(#Id IS NULL OR lngID = #Id) AND
(#blnIsinProgress IS NULL OR blnIsinProgress = #blnIsinProgress) AND
(#strStatus = '' OR strStatus = #strStatus) AND
(#strName= '' OR strName= #strName) AND
(#strConfirmationNumber = '' or #strConfirmationNumber = #strConfirmationNumber )
End
But
Execute spManage 1,0,'','',123
will give me all the results
The problem is this line:
(#strConfirmationNumber = '' or #strConfirmationNumber = #strConfirmationNumber )
The second condition is always true. You have an extra #. So, try this:
(#strConfirmationNumber = '' or #strConfirmationNumber = strConfirmationNumber )
declare #SP nvarchar(3)
SELECT HDR.SOPNUMBE, HDR.docdate, HDR.pymtrmid,
RTRIM(HDR.ShipToName) +
CASE WHEN HDR.ADDRESS1 <> '' THEN char(10) + RTRIM(HDR.ADDRESS1) ELSE '' END
FROM vSOPHdr HDR
WHERE HDR.SOPTYPE = 2 AND
(CASE WHEN HDR.SLPRSNID <> 'All'
then HDR.SLPRSNID in (''+#SP+'')
else HDR.SLPRSNID between '0' and 'ZZZZZZZZZZZZZZZ'
end)
I am trying to run the above query in sql query analyzer but getting 'syntax' errors in the CASE expression (near IN, ELSE). What could be wrong?
All I want to do is when sales-personID is selected as ALL in the report parameter I would like to process all sales person else only the selected sales person ID.
Just a background about what I am doing,
I have a similar query to the above query (without the CASE condition) within a dataset for a SSRS report.
Note that #SP is a report parameter.
CASE is an expression that returns a single value. It cannot be used for control-of-flow logic, like in other languages such as VB. Try:
WHERE HDR.SOPTYPE = 2 AND
((HDR.SLPRSNID <> 'All' AND HDR.SLPRSNID = #SP)
OR
(HDR.SLPRSNID = 'All'))
Though it seems like maybe you need instead, which would make more logical sense if the user is potentially passing 'All' into the parameter:
WHERE HDR.SOPTYPE = 2 AND
((#SP <> 'All' AND HDR.SLPRSNID = #SP)
OR
(#SP = 'All'))
you can just use an OR clause
WHERE HDR.SOPTYPE = 2 AND
((HDR.SLPRSNID <> 'All' AND HDR.SLPRSNID IN (''+#SP+''))
OR
(HDR.SLPRSNID = 'All' AND HDR.SLPRSNID BETWEEN '0' and 'ZZZZZZZZZZ'))
Not sure if the BETWEEN '0' and 'ZZZZZZZZZZZ' means "IN everything". If yes, you can just remove it now.
If you absolutely wanna use a CASE WHEN, you can do it this way :
WHERE HDR.SOPTYPE =2
AND (CASE WHEN HDR.SLPRSNID <>'All' AND HRD.SLPRSNDID IN (''+#SP+'')) THEN 1
WHEN HDR.SLPRSNID = 'All' AND HDR.SLPRSNID BETWEEN '0' and 'ZZZZZZZZZZ' THEN 1
ELSE 0
END) = 1
Is it possible to change these 2 queries into 1?
Query #1:
UPDATE `pvdownloader`.`posts`
SET `exists` = 'y'
WHERE source = ANY (SELECT source FROM dbdownloader.posts)
AND `mangacount` = 0
AND NOT `exists` = 'm'
Query #2:
UPDATE `pvdownloader`.`posts`
SET `exists` = 'n'
WHERE `exists` = 'u'
AND `mangacount` = 0
I'm assuming it would be possible to make something like this with IF/ELSE but I can't figure out how to use it at all :<
Maybe something like this would work:
update
pvdownloader.posts
set
exists =
case
when source = any(select source from dbdownloader.posts) and mangacount = 0 and exists != 'm' then 'y'
when exists = 'u' and mangacount = 0 then 'n'
end
where
(source = any(select source from dbdownloader.posts) and mangacount = 0 and exists != 'm')
or
(exists = 'u' and mangacount = 0)
;
As #MostyMostacho suggested, I took the liberty of changing your logic to not have a double-negative.