Using a Case statement to set a parameter based on another parameter - sql

I'm trying to set an SQL variable based on the numerical value of a different SQL parameter passed into a stored procedure, but having trouble with the exact syntax of the Case statement
DECLARE #RangeText varchar(1)
SELECT CASE
WHEN (#SecondsOnSiteRange = 1)
THEN SET #RangeText = '=' END
WHEN (#SecondsOnSiteRange = 2)
THEN SET #RangeText = '>' END
WHEN (#SecondsOnSiteRange = 3)
THEN SET #RangeText = '<' END
ELSE NULL
END
I'm sure it will be something small like a missing keyword or something, but when I search Google all I seems to be able to find is setting a the same variable, not a second one.

Correct syntax:
Simple CASE expression:
CASE input_expression
WHEN when_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
Searched CASE expression:
CASE
WHEN Boolean_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
Code:
DECLARE #RangeText varchar(1)
SELECT #RangeText = CASE
WHEN (#SecondsOnSiteRange = 1) THEN '='
WHEN (#SecondsOnSiteRange = 2) THEN '>'
WHEN (#SecondsOnSiteRange = 3) THEN '<'
ELSE NULL
END
or:
SELECT #RangeText = CASE #SecondsOnSiteRange
WHEN 1 THEN '='
WHEN 2 THEN '>'
WHEN 3 THEN '<'
ELSE NULL
END

You should only use end at the end like this:
SELECT CASE
WHEN (#SecondsOnSiteRange = 1)
THEN SET #RangeText = '=' ELSE
WHEN (#SecondsOnSiteRange = 2)
THEN SET #RangeText = '>' ELSE
WHEN (#SecondsOnSiteRange = 3)
THEN SET #RangeText = '<' ELSE
ELSE NULL
END
I am extremely sorry the above is incorrect. I did overlook, below is how it should be done...
SELECT #RangeText =
CASE WHEN (#SecondsOnSiteRange = 1)
THEN '='
WHEN (#SecondsOnSiteRange = 2)
THEN '>'
WHEN (#SecondsOnSiteRange = 3)
THEN '<'
ELSE NULL
END

Related

How do I use concat and case switch together in PostgresSQL?

I am trying to use concat as function and inside the same function use case switch statements in PostgresSQL. The end goal is populating a table with a bunch of statements that change according to the case.
Does anybody know how to solve this?
I tried to use '+' and ',' but I always get the same Syntax error
(SELECT concat(cast(idpersonale as varchar(5)),' = '
,case when dstitolo is not null then dstitolo else '' end + ' '
,case when dsnome is not null then dsnome else '' end + ' '
,case when dscognome is not null then dscognome else '' end
dscognome)
FROM global.glb_personale
WHERE cch.glb_personale.idpersonale =inter.interventoeseguitoda) as InterventoEseguitoDa
FROM cch.pats_cch_interventi inter
WHERE (idtiporecord is null or not idtiporecord in('uti','int')) and
NOT idintervento IN (SELECT idint
FROM cch.glo_error_data_2
WHERE (iddb = 'cch') AND (cnerror = 1))
order by idintervento;
Concatenation works with || operator or concat(text1, text2, text3, ...) function. Every text literal can be also an expression which gives a type text, like a CASE clause:
demo:db<>fiddle
SELECT
'you' || 'can' || 'concat' || 'like' || 'that' AS concat1,
concat('or', 'like', 'that') AS concat2,
concat('Mix' || 'both', 'up') AS concat3,
concat(
'And',
CASE WHEN false THEN 'now' ELSE 'doint' END || 'this',
CASE
WHEN true THEN 'with' || 'some'
WHEN false THEN 'CASE'
ELSE 'clauses'
END
) AS concat4
That means in your case: Change concat(text1 + text2 + text3) to concat(text1, text2, text3) (because the texts are function arguments) or to text1 || text2 || text3
since you are using concat(), replace + to , instead.
(SELECT concat(cast(idpersonale as varchar(5)),' = '
,case when dstitolo is not null then dstitolo else '' end, ' '
,case when dsnome is not null then dsnome else '' end, ' '
,case when dscognome is not null then dscognome else '' end
dscognome)
FROM global.glb_personale
WHERE cch.glb_personale.idpersonale =inter.interventoeseguitoda) as InterventoEseguitoDa
FROM cch.pats_cch_interventi inter
WHERE (idtiporecord is null or not idtiporecord in('uti','int')) and
NOT idintervento IN (SELECT idint
FROM cch.glo_error_data_2
WHERE (iddb = 'cch') AND (cnerror = 1))
While the concatenation operator (||) and the function (concat) combine strings there is a big difference between them: how they handle nulls.
If any operand is null then the concatenation operator result is NULL.
If any operand is null then the concatenation function moves to the next operand, leaving previous and subsequent results as they would had the null operand not been present. Example:
with dscognome (idpersonale,dstitolo ,dsnome ,dscognome) as
( values (1,'a','b','c')
, (2,'d','e',null)
, (3,'f',null,'g')
, (4,null, 'h', 'i')
, (5,null, null, null)
)
select idpersonale
, dstitolo || dsnome || dscognome "using || opreator"
, concat(dstitolo,dsnome,dscognome) "using concat function"
from dscognome;
Since the entire purpose of the case structure is to handle nulls, using the concatenation function entirely negates it's requirement and the query can be written:
with dscognome (idpersonale,dstitolo ,dsnome ,dscognome) as
( values (1,'a','b','c')
, (2,'d','e',null)
, (3,'f',null,'g')
, (4,null, 'h', 'i')
, (5,null, null, null)
)
SELECT concat(cast(idpersonale as varchar),' = '
, dstitolo , ' '
, dsnome, ' '
, dscognome )
from dscognome;

Using prompts in Select Case statements

I want to use select case for my prompts. Condition is that when the prompt :4 = 'I' then prompt :5 equals all of its values, and I use the code below but i receive the following error.
Error in running query because of SQL Error, Code=936, Message=ORA-00936: missing expression (50,380)
2 = 2 AND (CASE :5
WHEN :4 = 'I' AND :5 = ' '
THEN :5 = '%'
END)
Anything wrong with my case statemnt?
There are two different syntaxes for CASE:
CASE value1
WHEN value2 THEN expression1
WHEN value2 THEN expression2
ELSE expression3
END
and:
CASE
WHEN boolean_expression THEN expression1
WHEN boolean_expression THEN expression2
ELSE expression3
END
Note: The first statement can be converted to the second as
CASE
WHEN value1 = value2 THEN expression1
WHEN value1 = value3 THEN expression2
ELSE expression3
END
You are mixing these two syntaxes and it is invalid SQL.
You appear to want:
:5 = CASE WHEN :4 = 'I' AND :5 = ' ' THEN '%' END
However, even that will not work as bind variables are set once and are not re-evaluated so your logic would be:
( ( :4 = 'I' AND :5 = ' ' ) AND :5 = '%' )
OR ( NOT ( :4 = 'I' AND :5 = ' ' ) AND :5 = NULL )
Since :5 cannot ever be both ' ' and '%' then that branch of the logic can never be true and anything (including NULL) is never equal to NULL so the second branch of the logic is also never true; therefore your expression will never match anything.
Just create an expression like this
decode(:4,'I',:5,SOMEVALUEORFIELD) = :5
This is your case expression:
(CASE :5 WHEN :4 = 'I' AND :5 = ' ' THEN :5 = '%'
END)
I cannot figure out what you really want. Both the CASE :5 and the :5 = '%' are improper. Perhaps:
(CASE WHEN :4 = 'I' AND :5 = ' ' THEN '%'
END) as :5
However, you don't normally use parameters for column aliases.

Find an unmatched curly brackets in a string in SQL

How can I find an unmatched curly brackets in a string in SQL?
DECLARE #iVariable varchar(100)
SET iVariable = '{Day}{Month}{Year}'
If any unmatched left bracket found ({Day}{Month{Year}) then should return 'Unmatched {'
else any unmatched right bracket found ({Day}{Month}Year}) then should return 'Unmatched }'
If there is no unmatched brackets it shoud return the value in comma seperated format eg ('Day,Month,Year')
Is there any logic to do this?
What I would do is that I would validate the length of the string after replacing '{' with '' (empty string).
DECLARE #iVariable varchar(100) = '{Day}{Month}{Year}'
select case
when len(#iVariable) - len(replace(#iVariable, '{', '')) < len(#iVariable) - len(replace(#iVariable, '}', ''))
then 'Unmatched }'
when len(#iVariable) - len(replace(#iVariable, '{', '')) > len(#iVariable) - len(replace(#iVariable, '}', ''))
then 'Unmatched {'
else right(replace(replace(#iVariable, '{', ','), '}', ''), len(replace(replace(#iVariable, '{', ','), '}', '')) - 1)
end
What happens here is that I check if there are more '}' than '{', it returns unmatched '}'.
Likewise for '}'.
If the number matches, it returns the original string, with '{' and '}' replaced out, and commas inserted instead.
Edit: As Gordon stated in the comments, this does not work for for example '{}}{'.
Instead, You could use a user defined function. For instance:
create function SomeFunc(#iVariable varchar(2000))
returns varchar(3000)
as
begin
if len(replace(replace(#iVariable, '}', ''), '{', '')) = 0
return 'No data present'
else
begin
-- Declare stuff to be used
declare #result varchar(3000) = ''
declare #AMT_Left int = len(#iVariable) - len(replace(#iVariable, '{', ''))
declare #AMT_Right int = len(#iVariable) - len(replace(#iVariable, '}', ''))
-- First test if no. of brackets match:
if #AMT_Left > #AMT_Right
set #result = 'Unmatched }'
else if #AMT_Left < #AMT_Right
set #result = 'Unmatched {'
else if #AMT_Left = #AMT_Right
begin
-- If matched, define result, and use while loop for error handling
set #result = right(replace(replace(#iVariable, '{', ','), '}', ''), len(replace(replace(#iVariable, '{', ','), '}', '')) - 1)
DECLARE #intFlag INT
SET #intFlag = 1
-- Loop through each set and check if '{' occurs before '}':
WHILE (#intFlag <= #AMT_Left and #result != 'Non matching pair')
BEGIN
if charindex('{', #iVariable) > charindex('}', #iVariable)
set #result = 'Non matching pair'
set #iVariable = right(#iVariable, len(#iVariable) - charindex('}', #iVariable))
SET #intFlag = #intFlag + 1
end
end
end
return #result
end;
go
Testing with these input values:
select dbo.SomeFunc('{Day}{Month}{Year}')
select dbo.SomeFunc('{Day}{Month{Year}')
select dbo.SomeFunc('{Day}{Month}Year}')
select dbo.SomeFunc('{}{}')
select dbo.SomeFunc('{}}{')
select dbo.SomeFunc('{Day}}Month{')
result:
Day,Month,Year
Unmatched }
Unmatched {
No data present
No data present
Non matching pair
There may be a more elegant way to do this, but the following should capture all the cases:
with v as (
select '{Day}{Month}{Year}' as var union all
select '{Day}{Month}{Year}}{' union all
select '{Day}{Month}{Year}}}'
),
cte as (
select left(var, 1) as c, 1 as num, var
from v
union all
select substring(var, num+1, 1), num + 1, var
from cte
where num <= len(var)
)
select var,
(case when min(balance) < 0 then 'Unbalanced }'
when sum(case when c = '{' then 1
when c = '}' then -1
else 0
end) > 0
then 'Unbalanced {'
else 'Balanced'
end)
from (select cte.*,
(select sum(case when c = '{' then 1
when c = '}' then -1
else 0
end)
from cte cte2
where cte2.var = cte.var and cte2.num <= cte.num
) as balance
from cte
) t
group by var;
This explodes the values character by character and then checks for the balance.

Syntax Errors With Case Statement in SQL

If the When conditions are correct, then I want it to be labeled as 'Suspended for Audit....' if they are not correct, then have it be either blank or filled in by the t.fstrTaskSource + 'TYP' + t.fstrType statement (this part works already)
SELECT t.flngKey AS flngTaskKey,
t.fstrAccountType,
t.fstrTaskSource,
CASE t.fstrCategory
WHEN '' THEN ''
ELSE t.fstrTaskSource + '_CAT_' + t.fstrCategory
END AS fstrCategory,
CASE t.fstrType
WHEN '' THEN ''
WHEN (wd.fstrWorkType = 'SUSIN1' -- I am getting a syntax error here on the = sign --
AND wd.fstrOwner = ' '
AND wd.flngworkkey = wr.flngworkkey
AND wr.fstrAccountType <> '007'
AND wr.fblnOpen = 1
AND EXISTS
(SELECT 1
FROM tblIndicator i
WHERE i.fstrIndicator = 'EIWTCH'
AND i.flngVer = 0
AND i.flngAccountKey = wd.flngAccountKey)) -- I am also getting an error here on the ) sign --
THEN 'Suspended for Audit Indicator - EIC Watch For'
ELSE t.fstrTaskSource + '_TYP_' + t.fstrType
END AS fstrType
Your second Case Expression is a mix of Simple Case and Searched Case.
I.e.
CASE t.fstrType
WHEN '' THEN ''
WHEN (wd.fstrWorkType = 'SUSIN1'
Change it to a Searched Case expression as:
CASE WHEN t.fstrType = '' THEN ''
WHEN (wd.fstrWorkType = 'SUSIN1' ...
Two formats of Case Expression are:
--Simple CASE expression:
CASE input_expression
WHEN when_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
--Searched CASE expression:
CASE
WHEN Boolean_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
Your are trying to use the two syntax of CASE in the same time
the first:
case expression
when "val1" then ..
when "val2" then ..
end
the second:
case
when column = "val1" then ..
when column2 = "val2" then ..
end
So, use this in your second CASE:
CASE
WHEN t.fstrType = '' THEN ''
WHEN (wd.fstrWorkType = 'SUSIN1' ...

Invalid column names ERROR

i have a simple query below. but I don't know why I am getting an invalid column names error for field names and error value in where clause.
select * From (
select [SubscriberDataId]
,Case When ISNUMERIC([SubscriberCode]) = 0 Then cast([SubscriberCode]as varchar(9)) Else '~' end as [SubscriberCode]
,Case When ISDATE([Dob]) = 0 Then Cast([Dob] as Varchar(9)) Else '~' end as [Dob]
,Case When ISNUMERIC([FacetsGroup]) = 0 Then cast([FacetsGroup]as varchar(9)) Else '~' end as [FacetsGroup]
from Facets.SubscriberData) [sd]
Unpivot
(ErrorValue for FieldName in ([SubscriberCode],
[Dob],[FacetsGroup])) as x
where x.ErrorValue <> '~' and
NOT EXISTS (SELECT *
FROM Elig.dbo.ErrorTable
WHERE TableName = facets.SubscriberData
AND FieldName IN( [x].[SubscriberCode],[x].[Dob],[x].[FacetsGroup])
AND ErrorValue IN( [SubscriberCode],[Dob],[FacetsGroup]))
try
select * From
(select [SubscriberDataId],
Case When ISNUMERIC([SubscriberCode]) = 0
Then cast([SubscriberCode]as varchar(9))
Else '~' end as [SubscriberCode],
Case When ISDATE([Dob]) = 0
Then Cast([Dob] as Varchar(9))
Else '~' end as [Dob],
Case When ISNUMERIC([FacetsGroup]) = 0
Then cast([FacetsGroup]as varchar(9))
Else '~' end as [FacetsGroup]
from Facets.SubscriberData) [sd]
Unpivot (ErrorValue for FieldName in ([SubscriberCode], [Dob],[FacetsGroup])) as x where x.ErrorValue <> '~'
and NOT EXISTS (SELECT * FROM Elig.dbo.ErrorTable
WHERE TableName = facets.SubscriberData
AND FieldName IN( '[x].[SubscriberCode]','[x].[Dob]','[x].[FacetsGroup]')
AND ErrorValue IN( '[SubscriberCode]','[Dob]','[FacetsGroup]'))