Assign to a T-SQL variable from a CASE statement - sql

I'd like to assign some variables inside a query that uses CASE statements for it's columns. Not quite sure how to do this, having trouble finding the right syntax.
This is what I have so far, but it's got syntax errors.
-- set #theID and #theName with their appropriate values
select top (1)
#theID = (Case when B.ID IS NULL then A.ID else B.ID END) ,
#theName = (Case when B.Name IS NULL then A.Name else B.Name END)
from B left join A on A.ID = B.ID where ...
What's the correct place/way to stick those variables in there?

The example you've given should work. You can assign to variables from a case statement. Just pretend that the entire CASE..WHEN..THEN..ELSE..END block is a field. Here is a generic example:
declare #string1 nvarchar(100) = null
declare #string2 nvarchar(100) = null
select
#string1 = case when 1=1 then 'yes' else 'no' end
,#string2 = case when 1=0 then 'yes' else 'no' end
print 'string1 = ' + #string1
print 'string2 = ' + #string2
Gives:
string1 = yes
string2 = no
Can you tell us what specific error(s) you are getting?

You could probably do this more easily using ISNULL or COALESCE:
select top (1)
#theID = ISNULL(B.ID, A.ID),
#theName = ISNULL(B.Name, A.Name),
from B left join A on A.ID = B.ID where ...

DECLARE #SmallBlindSeatId INT
DECLARE #BigBlindSeatId INT
DECLARE #DealerSeatId INT
DECLARE #NextTurn INT
SELECT #DealerSeatId=( CASE WHEN BlindsInfo=1 THEN SeatId ELSE #DealerSeatId END ),
#SmallBlindSeatId=( CASE WHEN BlindsInfo=2 THEN SeatId ELSE #SmallBlindSeatId END),
#BigBlindSeatId=( CASE WHEN BlindsInfo=3 THEN SeatId ELSE #BigBlindSeatId END),
#NextTurn=( CASE WHEN NEXTTURN=1 THEN SeatId ELSE #NextTurn END)
FROM ABC WHERE TESTCASEID=1
PRINT(#DealerSeatId)
PRINT(#SmallBlindSeatId)
PRINT(#BigBlindSeatId)
PRINT (#NextTurn)

Related

SQL CASE wrong output

I have this weird encounter using CASE in sql 2014.
This is my query:
SELECT (CASE WHEN dbo.GetFunctionAge(C.Birthdate) = 0
THEN '' ELSE dbo.GetFunctionAge(C.Birthdate)
END) AS Age
,dbo.GetFunctionAge(C.Birthdate)
,c.Birthdate
FROM Client C
WHERE ClientID = '34d0d845-e3a6-4078-8936-953ff3378eac'
this is the output:
Here is the GetFunctionAge function if you might ask.
IF EXISTS (
SELECT *
FROM dbo.sysobjects
WHERE ID = OBJECT_ID(N'[dbo].[GetFunctionAge]') AND
xtype in (N'FN', N'IF', N'TF'))
DROP FUNCTION [dbo].[GetFunctionAge]
GO
CREATE FUNCTION [dbo].[GetFunctionAge](#BirthDate DATETIME)
RETURNS INT
AS
BEGIN
DECLARE #Age INT
IF(#BirthDate = '1753-01-01 00:00:00.000')
BEGIN
SET #Age = 0
END
ELSE
BEGIN
SET #Age = DATEDIFF(hour,#BirthDate,GETDATE())/8766
END
RETURN #Age
END
GO
Question:
Why is Column Age in my output is 0which should be ''?
I added (No column name) to show that its output is 0 so my expected output base from my case condition is '' not 0
I didn't receive any error regarding inconsistency of data so why is case behaving like that?
Thanks for those who could clarify this to me.
SELECT
(CASE
WHEN a.ageint = 0 THEN ''
ELSE cast(a.ageint as varchar(3))
END) AS Age
, a.ageint
, c.Birthdate
FROM Client as C
CROSS APPLY (
SELECT
ISNULL(dbo.GetFunctionAge(C.Birthdate), 0) AS ageint
) AS a
WHERE ClientID = '34d0d845-e3a6-4078-8936-953ff3378eac'
;
You can cast it into varchar so you can return ' '.
SELECT (CASE WHEN dbo.GetFunctionAge(C.Birthdate) = 0
THEN '' ELSE Cast(dbo.GetFunctionAge(C.Birthdate) as varchar(5))
END) AS Age
,dbo.GetFunctionAge(C.Birthdate)
,c.Birthdate
FROM Client C
WHERE ClientID = '34d0d845-e3a6-4078-8936-953ff3378eac'
But If you wish to remain your Age column in data type int.
You could just use NULL instead of ' '

case statement in where clause depending on variable value

Depending on variable value my Where condition should change
If #CustID <> 0 Then
Where SomeColumn = #BillID
Else
Where SomeColumn In (#BillID,0)
My Query:
Select *
From SomeTable
Where SomeColumn = (Case When #CustID <> 0 Then #BillID Else /* What to Write Here */ End)
Here is the query you're looking for:
SELECT *
FROM SomeTable ST
WHERE (#CustID <> 0 AND ST.SomeColumn = #BillID)
OR (#CustID = 0 AND ST.SomeColumn IN (#BillID, 0))
Hope this will help.

Transact-SQL stored procedure with conditional "AND" logic

I'm working on a stored procedure that is used to filter a grid based on criteria entered by the user. Among the possible criteria they may choose to see transactions that were done between a certain begin and end date. I pass 4 input parameters to the proc - #ClientKey, the client requesting the info, #FilterBy (this is the selected value from a dropdown list in ASP.NET, and essentially tells the proc whether the user is selecting to filter by name, address, date, etc. In this case the #FilterBy value for date is 5), #Value1, which in this instance would be the begin date, and #Value2, which in this instance would be the end date.
In pseudo-code, what I want is:
SELECT ABunchOfColumns
FROM SomeJoinedTables
WHERE SomeCriteria
AND CASE #FilterBy
WHEN 5 THEN d.TransactionTime >= CAST(#Value1 AS Date) AND d.TransactionTime <= CAST(#Value2 AS Date)
Below is the full query. I hope that someone who is more savvy than me with SQL can sort out what I'm trying to do and offer a solution.
Thanks in advance!
#ClientKey int,
#FilterBy int,
#Value1 varchar(150),
#Value2 varchar(150)
AS
BEGIN
SELECT d.pKey AS PaymentKey, d.CaseKey, d.InvoiceID, d.AuthorizationCode, d.TransactionID, d.PaymentType, d.Amount, d.ExpirationDate, d.CardType, d.BankName, d.AccountNumber,
d.AccountType, c.Name, c.Address1, c.City, c.State, c.Zip, cs.PAmount, cs.TranCode, cs.TranDate, cs.[Desc] AS PaymentDescription, cc.[Desc] AS ChargeCodeDescription,
d.TransactionTime, a.Name AS AssociationName, d.PaymentType, c.ClientPaymentID
FROM DebtorPayment d INNER JOIN Cases c
ON d.CaseKey = c.pKey
AND d.ClientKey = c.ClientKey
INNER JOIN CaseSumm cs
ON d.CaseKey = cs.CaseKey
AND d.pKey = cs.Batch
AND d.ClientKey = cs.ClientKey
INNER JOIN ChargeCodes cc
ON c.ClientKey = cc.ClientKey
AND cs.TranCode = cc.RefNum
INNER JOIN AssnCtrl a
ON c.AssnKey = a.pKey
WHERE c.ClientKey = #ClientKey
AND d.AmountAllocated > 0
AND d.TransactionStatus = 'Successful'
AND c.Address1 LIKE CASE
WHEN #FilterBy = 1 THEN '%' + #Value1 + '%'
ELSE c.Address1
END
AND d.Amount = CASE
WHEN #FilterBy = 2 THEN #Value1
ELSE d.Amount
END
AND a.pKey = CASE
WHEN #FilterBy = 3 THEN CAST(#Value1 AS INT)
ELSE a.pKey
END
AND c.ClientPaymentID = CASE
WHEN #FilterBy = 4 THEN #Value1
ELSE c.ClientPaymentID
END
<ProblemArea>
AND CASE #FilterBy
WHEN 5 THEN d.TransactionTime >= CAST(#Value1 AS Date) AND d.TransactionTime <= CAST(#Value2 AS Date)
END
</ProblemArea>
AND c.LName LIKE CASE
WHEN #FilterBy = 6 THEN '%' + #Value1 + '%'
ELSE c.LName
END
ORDER BY d.TransactionTime DESC
END
CASE
WHEN #FilterBy = 5 AND d.TransactionTime >= CAST(#Value1 AS DATE)
AND d.TransactionTime <= CAST(#Value2 AS DATE) THEN 1
ELSE 0
END = 1
Do you mean something like the following?
You might find this link useful too.
Haven't tested the code, just proposing idea - and writing code like this has always felt "wrong" to me - perhaps someone could offer better.
CREATE PROC MyProc
#ClientKey int,
#FilterBy int,
#Value1 varchar(150),
#Value2 varchar(150)
-- NB WITH RECOMPILE, see link (above)
WITH RECOMPILE AS
BEGIN
SET NOCOUNT ON;
SELECT *
FROM ...
WHERE
Col1 = CASE
WHEN #FilterBy = 1 THEN #Value1
ELSE Col1
END
AND
1 = CASE
WHEN #FilterBy = 2 AND Col2 > #Value1 AND Col3 < #Value2 THEN 1
WHEN #FilterBy = 2 AND NOT (Col2 > #Value1 AND Col3 < #Value2) THEN 0
ELSE 1
END
END

SQL Nested CASE - shortcut logic?

I am trying to get rid of all of my dynamic SQL code. This stored procedure seems to require some nested CASE statements withing the WHERE clause. This is working as expected. However, I am worried about the performance. Will the nested ( GuarantorNumber not in ( select... ) ) statements be executed if the parent CASE statements are not true?
WHERE 1 = CASE WHEN ( #method='ADDED_RECORDS' ) THEN
CASE WHEN
( pt.[GuarantorNumber] not in (select cpg.GuarantorNumber from [CorepointProtectedGuarantor] cpg) ) THEN
1
ELSE 0 END -- NEW_RECORDS
WHEN ( #method='DELETED_RECORDS' ) THEN
CASE WHEN
( pt.[GuarantorNumber] not in (select mpg.GuarantorNumber from [MeditechProtectedGuarantor] mpg) ) THEN
1
ELSE 0 END -- DELETED_RECORDS
WHEN ( #method='UPDATED_RECORDS' ) THEN
CASE WHEN
( pt.[GuarantorNumber] in
(SELECT mpg.GuarantorNumber FROM
[MeditechProtectedGuarantor] mpg,
[CorepointProtectedGuarantor] cpg
WHERE
mpg.GuarantorNumber = cpg.GuarantorNumber and
(mpg.[LastName] <> cpg.[LastName] OR
mpg.[FirstName] <> cpg.[FirstName] OR
mpg.[MiddleName] <> cpg.[MiddleName] OR
mpg.[Address] <> cpg.[Address] OR
mpg.[AddressLine2] <> cpg.[AddressLine2] OR
mpg.[City] <> cpg.[City] OR
mpg.[State] <> cpg.[State] OR
mpg.[ZIP] <> cpg.[ZIP] OR
mpg.[Phone] <> cpg.[Phone])
) -- end of SELECT clause
) -- end of WHEN clause
THEN
1
ELSE 0 END -- UPDATED_RECORDS
Searched CASE expression:
Returns the result_expression of the first input_expression = when_expression that evaluates to TRUE.
In your case if #method='ADDED_RECORDS' and #method='DELETED_RECORDS' are false then the next statement will be executed WHEN(#method='UPDATED_RECORDS') In SQLServer2008 to analysе this behavior symply by pressing Cntl+L.
Declare #query nvarchar(max)
Declare #selectoneCount int
Declare #Temp int
SET #Temp =1
Declare #val nvarchar(max)
SET #val =''
select
#query = case #Temp
when 1
then
case #val
when 'NULL'
then
('Select Diameter from BallsProbes where Remark =2')
else
('Select Diameter from BallsProbes where Remark =3')
END
when 2
then ('Select Diameter from BallsProbes where Remark =6')
end
EXEC(#query)

Sql Server conditional Contains for free text search handling of Null parameter

I have been struggling for quite some time to get this query going.
In short my query searches by fileno and/or searchfield
DECLARE #pSearchFor AS NVARCHAR(100);
-- I am here testing with null value, ' ' , or seperate words
SET #pSearchFor = null -- '"marsa" and "mosta"';
IF ISNULL(#pSearchFor,'') = '' SET #pSearchFor = '""' ;
declare #fileNo nvarchar(50) = 'e/e'
select top 1000 r.FileId, r.FileNo, fs.SearchField, #pSearchFor
from regfile as r
left outer join FileSearchFields as fs on r.FileId = fs.FileID
where r.FileNo like
CASE
WHEN Len(#fileno) > 1 THEN '%'+#fileNo+'%'
ELSE r.FileNo
END
AND
1 =
CASE WHEN ISNULL(#pSearchFor, '') = '' THEN 1 ELSE 0 END
or CONTAINS(fs.SearchField, #pSearchFor)
I am getting nothing returned if #pSearchFor is null otherwise works great.
I need to return all instances if a null
One possible solution might be to call 2 seperate sps or use if /else but probably exists a better method.
I really do appreciate your help!
First you set #pSearchFor to "":
IF ISNULL(#pSearchFor,'') = '' SET #pSearchFor = '""' ;
That means this will never return 1:
CASE WHEN ISNULL(#pSearchFor, '') = '' THEN 1 ELSE 0 END
You need to either use a different variable, or use the same type of CASE expression in the select list, instead of changing the value from NULL to "".
SELECT TOP 1000 r.FileId, r.FileNo, fs.SearchField,
CASE WHEN COALESCE(#pSearchFor, '') = '' THEN '""' ELSE #pSearchFor END
Also you use SELECT TOP but no ORDER BY ... if you want a subset, don't you care which subset you get?
I have solved the problem. Maybe this may be of some help to others!
This is a snippet of my stored procedure.
#fileNo nvarchar(50) = null ,
#fields nvarchar(100) = '""',`enter code here`
#datefrom date = null,
#dateto date = null,
...
AS`enter code here`
BEGIN
if (#fields = null or LEN(#fields) < 1 ) set #fields = '""'
select top 1000 r.*,
(CASE
WHEN fs.SearchField IS NULL THEN CONVERT(NVarChar(1),'')
ELSE CONVERT(NVarChar(MAX),fs.SearchField)
END) AS [Search]
from regfile as r
left outer join FileSearchFields as fs on r.FileId = fs.FileID
where r.FileNo like
CASE
WHEN Len(#fileno) > 1 THEN '%'+#fileNo+'%'
ELSE r.FileNo
END
and
r.Date between
CASE
WHEN #datefrom != '' THEN #datefrom
ELSE '1900-1-1'
END
and
CASE
WHEN #dateto != '' THEN #dateto
ELSE '9999-1-1'
END
and
((LEN(#fields) > 2 and contains(fs.SearchField,#fields))or (LEN(#fields) <= 2))
--NB: <= 2 as we have added the "" characters in #fields!
end