If else ladder using Case in sql server - sql

I am trying to write if elif ladder in SQL but I am finding it little difficult to do that. My ladder looks like below.
IF (MortgageProduct.FreeLegalFees != NULL) THEN
IF(MortgageProduct.FreeLegalFees==1) THEN
Return TRUE as FreeLegalFees
ELSE
Return FALSE as FreeLegalFees
ELSE
IF (ConveyancerFee!=NULL) THEN
IF ConveyancerFee.AMOUNT = 0.0 then
Return TRUE as FreeLegalFees
ELSE
Return FALSE as FreeLegalFees
END IF
ELSE
IF (LenderFee!=NULL) THEN
IF LenderFee.AMOUNT = 0.0 then
Return TRUE as FreeLegalFees
ELSE
Return FALSE as FreeLegalFees
END IF
ELSE
Return TRUE as FreeLegalFees
END IF
I know that I have to use Case for that in SQL but I am confuse in writing Case statement in sql. Can somebody please help me to frame this ladder in sql server.

This is far more succinct. I have also aliased what I assume are your table names:
CASE WHEN MP.FreeLegalFees IS NOT NULL THEN IIF(MP.FreeLegalFees = 1,1,0)
WHEN CF.AMOUNT IS NOT NULL THEN IIF(CF.AMOUNT = 0,1,0)
WHEN LF.Amount IS NOT NULL THEN IIF(LF.AMOUNT = 0,1,0)
ELSE 1 END
/*
MP MortgageProduct
CF ConveyancerFee
LF LenderFee
*/

I would write this as:
(case when mp.FreeLegalFees = 1 then 1
when mp.FreeLegalFees is not null then 0
when cf.amount = 0.0 then 1
when cf.amount is not null then 0
when lf.amount = 0.0 then 1
when lf.amount is not null then 0
else 1
end) as FreeLegalFees

CASE
WHEN MP.FREELEGALFEES = 1 THEN 1
WHEN MP.CONVEYANCERLEGALFEESET IS NOT NULL THEN
(
CASE
WHEN (
(SELECT AMOUNT FROM CONVEYANCERLEGALFEE WHERE LOCATION=#p_iLocation
and TYPEOFAPPLICATION=#p_iTypeOfApplication
and TYPEOFBUYER=#p_iTypeOfBuyer and MAXIMUMVALUE=100000
and CONVEYANCERLEGALFEESETSTRTDATE <= (SELECT GETDATE())
and CONVEYANCERLEGALFEESET = MP.CONVEYANCERLEGALFEESET ) = 0.0)
THEN 1
ELSE 0
END
)
WHEN ((Select COUNT(FEESET) FROM LEGALFEE WHERE TYPEOFAPPLICATION=#p_iTypeOfApplication
AND FEETYPE = (Select VALUEID from COMBOVALUE where VALUENAME='Redeeming')) >= 1 ) THEN
(
CASE
WHEN (
(SELECT AMOUNT FROM LEGALFEE
WHERE TYPEOFAPPLICATION = #p_iTypeOfApplication
AND FEETYPE= (SELECT VALUEID FROM COMBOVALUE WHERE VALUENAME='Redeeming')) = 0.0)
THEN 1
ELSE 0
END
)
ELSE 1
This is the solution which works perfect. Thank you all.

CASE
WHEN MortgageProduct.FreeLegalFees IS NOT NULL
THEN (
CASE
WHEN MortgageProduct.FreeLegalFees = 1
THEN 'TRUE'
ELSE 'FALSE'
END
)
WHEN ConveyancerFee IS NOT NULL
THEN (
CASE
WHEN ConveyancerFee.AMOUNT = 0.0
THEN 'TRUE'
ELSE 'FALSE'
END
)
WHEN LenderFee IS NOT NULL
THEN (
CASE
WHEN LenderFee.AMOUNT = 0.0
THEN 'TRUE'
ELSE 'FALSE'
END
)
ELSE 'TRUE'
END AS FreeLegalFees

Related

ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 4448, maximum: 4000)

I am trying to Migrate client's data and this error happened during the migration procedure. I have searched around and the possible solution is to trim or use DBMS_LOB.SUBSTR, but i do not know where to put them in. It could be this part (TO_CHAR(AIMSCMDDL_AT.BIOS_SEQ.nextval) but i am still new to SQL and not sure what could be the cause of the problem. Can anyone guide me on how to solve this problem? Thank you!
Update
AIMSCMDDL_AT.AI_OPENNET_SVC_RPT
SET
CUST_AGREEMENT_SIGNATURE =
CASE
WHEN TO_CHAR(CUST_AGREEMENT_SIGNATURE) = null
THEN null
ELSE 'NULL'
END
, CUST_DECLARATION_AUTH_ID =
CASE
WHEN CUST_DECLARATION_AUTH_ID = null
THEN null
ELSE
CASE WHEN LENGTH(CUST_DECLARATION_AUTH_ID)<>9
THEN TO_CHAR(AIMSCMDDL_AT.BIOS_SEQ.nextval)
ELSE
CASE WHEN LENGTH(CUST_DECLARATION_AUTH_ID)=9
and REGEXP_LIKE(substr(CUST_DECLARATION_AUTH_ID,1,1),'[A-Za-z]')
and REGEXP_LIKE(substr(CUST_DECLARATION_AUTH_ID,-1,1), '[A-Za-z]')
and AIMSCMDDL_AT.is_number(substr(CUST_DECLARATION_AUTH_ID,2,7)) = 1
THEN substr(CUST_DECLARATION_AUTH_ID,1,1)||LPAD(TO_CHAR(AIMSCMDDL_AT.BIOS_SEQ.nextval),7,'0')||substr(CUST_DECLARATION_AUTH_ID,-1,1)
ELSE TO_CHAR(AIMSCMDDL_AT.BIOS_SEQ.nextval)
END
END
END
, CUST_DECLARATION_AUTH_NM =
CASE
WHEN CUST_DECLARATION_AUTH_NM = null
THEN null
ELSE REGEXP_REPLACE(CUST_DECLARATION_AUTH_NM,'[[:alpha:]^[:digit:]^[:punct:]^]','*')
END
, CUSTOMER_SIGNATURE =
CASE
WHEN TO_CHAR(CUSTOMER_SIGNATURE) = null
THEN null
ELSE 'NULL'
END
, INSTALLER_NM =
CASE
WHEN INSTALLER_NM = null
THEN null
ELSE REGEXP_REPLACE(INSTALLER_NM,'[[:alpha:]^[:digit:]^[:punct:]^]','*')
END
, INSTALLER_SIGNATURE =
CASE
WHEN TO_CHAR(INSTALLER_SIGNATURE) = null
THEN null
ELSE 'NULL'
END
, REJ_CUSTOMER_ID =
CASE
WHEN REJ_CUSTOMER_ID = null
THEN null
ELSE
CASE WHEN LENGTH(REJ_CUSTOMER_ID)<>9
THEN TO_CHAR(AIMSCMDDL_AT.BIOS_SEQ.nextval)
ELSE
CASE WHEN LENGTH(REJ_CUSTOMER_ID)=9
and REGEXP_LIKE(substr(REJ_CUSTOMER_ID,1,1),'[A-Za-z]')
and REGEXP_LIKE(substr(REJ_CUSTOMER_ID,-1,1), '[A-Za-z]')
and AIMSCMDDL_AT.is_number(substr(REJ_CUSTOMER_ID,2,7)) = 1
THEN substr(REJ_CUSTOMER_ID,1,1)||LPAD(TO_CHAR(AIMSCMDDL_AT.BIOS_SEQ.nextval),7,'0')||substr(REJ_CUSTOMER_ID,-1,1)
ELSE TO_CHAR(AIMSCMDDL_AT.BIOS_SEQ.nextval)
END
END
END
, REJ_CUSTOMER_NM =
CASE
WHEN REJ_CUSTOMER_NM = null
THEN null
ELSE REGEXP_REPLACE(REJ_CUSTOMER_NM,'[[:alpha:]^[:digit:]^[:punct:]^]','*')
END
, REJ_CUSTOMER_SIGNATURE =
CASE
WHEN TO_CHAR(REJ_CUSTOMER_SIGNATURE) = null
THEN null
ELSE 'NULL'
END
, REJ_INSTALLER_NM =
CASE
WHEN REJ_INSTALLER_NM = null
THEN null
ELSE REGEXP_REPLACE(REJ_INSTALLER_NM,'[[:alpha:]^[:digit:]^[:punct:]^]','*')
END
, REJ_INSTALLER_SIGNATURE =
CASE
WHEN TO_CHAR(REJ_INSTALLER_SIGNATURE) = null
THEN null
ELSE 'NULL'
END
;
Most likely it comes from one of these expressions:
CASE
WHEN TO_CHAR(INSTALLER_SIGNATURE) = null
THEN null
ELSE 'NULL'
END
First, they don't work. ... = NULL never yields TRUE. Is IS NULL instead.
There is no need to use TO_CHAR(), IS NULL works for any data type.
And you can write it shorter as
INSTALLER_SIGNATURE = NVL2(INSTALLER_SIGNATURE, 'NULL', NULL)
NB,
REGEXP_LIKE(substr(CUST_DECLARATION_AUTH_ID,1,1),'[A-Za-z]')
and REGEXP_LIKE(substr(CUST_DECLARATION_AUTH_ID,-1,1), '[A-Za-z]')
can be written as
REGEXP_LIKE(CUST_DECLARATION_AUTH_ID,'^[A-Za-z].*[A-Za-z]$')

SQL working strange

When I execute this SQL code:
select id, opis, vidrabota, tipprov, hitnost, valuta, drzava, zbirnaprov, tip_zbirprov, kanal
from dev_1450autoebanktip
where opis is null or Opis like case when isnull('','') = '' then Opis else '%' + '' + '%' end
and VidRabota = case when isnull('','') = '' then VidRabota else '' end
and TipProv = case when isnull(0,0) = 0 then TipProv else 0 end
and Valuta = case when isnull('','') = '' then Valuta else '' end
and drzava is null or Drzava = case when isnull('','') = '' then Drzava else '' end
I get this set of results:
But when I add one more condition (last row):
select id, opis, vidrabota, tipprov, hitnost, valuta, drzava, zbirnaprov, tip_zbirprov, kanal
from dev_1450autoebanktip
where opis is null or Opis like case when isnull('','') = '' then Opis else '%' + '' + '%' end
and VidRabota = case when isnull('','') = '' then VidRabota else '' end
and TipProv = case when isnull(0,0) = 0 then TipProv else 0 end
and Valuta = case when isnull('','') = '' then Valuta else '' end
and drzava is null or Drzava = case when isnull('','') = '' then Drzava else '' end
and KANAL = case when isnull(0,0) = 0 then KANAL else 0 end
I am losing one row in the result. What is causing this change?
Kanal is NULL in the last row.
and KANAL = case when isnull(0,0) = 0 then KANAL else 0 end
boils down to
and KANAL = KANAL
But this is not true for NULL, because NULL is the unknown value. When comparing null with null the result is neither true nor false, but unknown. Thus the added criteria dismisses the last record.
There is one thing I'd like to add: Use parentheses when mixing AND and OR. For instance
a = b or a = c and d = e
means
a = b or (a = c and d = e)
because AND has precedence over OR and you may want the expression to mean
(a = b or a = c) and d = e
Use parentheses in order to avoid any mistakes.

Nested CASE WHEN statement

I have one CASE WHEN condition (CompanyGUID and LineGUID) and I need 4 different calculations with 4 different columns.
The calculation works fine, but I just wonder is any way to make it more convenient? like for example maybe using COALESCE trick in this case?
CASE WHEN dbo.tblCompanyLocations.CompanyGUID = '29634AF7-D0A2-473D-9574-405C23E10F02'
AND dbo.tblQuotes.LineGUID = '1CB72920-B3FC-4822-8030-37B50A2810EB'
THEN isnull(ddaWC.archexMod,1)
END as ExperienceMod,
CASE WHEN dbo.tblCompanyLocations.CompanyGUID = '29634AF7-D0A2-473D-9574-405C23E10F02'
AND dbo.tblQuotes.LineGUID = '1CB72920-B3FC-4822-8030-37B50A2810EB'
THEN case when convert(int,ddawc.premModTtl) <= 0 then 1
when convert(int,ddawc.premModTtl) >= 0
then (1 + ddaWC.premschmod / ddawc.premModTtl) end
END as ScheduleMod,
CASE WHEN dbo.tblCompanyLocations.CompanyGUID = '29634AF7-D0A2-473D-9574-405C23E10F02'
AND dbo.tblQuotes.LineGUID = '1CB72920-B3FC-4822-8030-37B50A2810EB'
THEN isnull(ddaWC.TMpercent,1) END as TerritoryMod,
CASE WHEN dbo.tblCompanyLocations.CompanyGUID = '29634AF7-D0A2-473D-9574-405C23E10F02'
AND dbo.tblQuotes.LineGUID = '1CB72920-B3FC-4822-8030-37B50A2810EB'
THEN case when convert(int,ddaWC.SchedPercent) = 0 or
ddaWC.SchedPercent is not null
then (isnull(ddaWC.archexMod,1)
* (convert(decimal(5,2),isnull(ddaWC.SchedPercent,1))))
* isnull(ddaWC.TMpercent,1)
when ddaWC.SchedPercent is null
then 1 END
END as EffectiveMod
Something like this? The OUTER APPLY will perform a row-based select which return NULLs in case of your condition not being fullfilled. Otherwise it will return the same values you've specified. This will only work, if you really need the same logic for all columns.
SELECT otherColumn
,ConditionalColumns.*
FROM YourTable
OUTER APPLY
(
SELECT isnull(ddaWC.archexMod,1) as ExperienceMod,
case when convert(int,ddawc.premModTtl) <= 0 then 1
when convert(int,ddawc.premModTtl) >= 0
then (1 + ddaWC.premschmod / ddawc.premModTtl) end as ScheduleMod,
isnull(ddaWC.TMpercent,1) as TerritoryMod,
case when convert(int,ddaWC.SchedPercent) = 0 or ddaWC.SchedPercent is not null
then (isnull(ddaWC.archexMod,1)
* (convert(decimal(5,2),isnull(ddaWC.SchedPercent,1))))
* isnull(ddaWC.TMpercent,1)
when ddaWC.SchedPercent is null
then 1 END as EffectiveMod
WHERE dbo.tblCompanyLocations.CompanyGUID = '29634AF7-D0A2-473D-9574-405C23E10F02'
AND dbo.tblQuotes.LineGUID = '1CB72920-B3FC-4822-8030-37B50A2810EB'
) AS ConditionalColumns
Like this:
somewhere before code:
Declare #compGuid char(37) = '29634AF7-D0A2-473D-9574-405C23E10F02'
Declare #lineGuid char(37) = '1CB72920-B3FC-4822-8030-37B50A2810EB'
and modify From Clause in SQL statement to define aliases
cl for tblCompanyLocations, and
q for tblQuotes
then the case in the Select clause of the SQL code could be reduced to:
case when cl.CompanyGUID = #compGuid
and q.LineGUID = #lineGuid
then isnull(ddaWC.archexMod,1) end ExperienceMod,
case when cl.CompanyGUID = #compGuid
and q.LineGUID = #lineGuid
then case when cast(ddawc.premModTtl as int) > 0
then (1 + ddaWC.premschmod / ddawc.premModTtl)
else 1 end end ScheduleMod,
case when cl.CompanyGUID = #compGuid
and q.LineGUID = #lineGuid
then isnull(ddaWC.TMpercent,1) end TerritoryMod,
case when cl.CompanyGUID = #compGuid
and q.LineGUID = #lineGuid
then case when cast(ddaWC.SchedPercent as int) = 0
then isnull(ddaWC.archexMod,1)
* cast(ddaWC.SchedPercent as decimal(5,2)))
* isnull(ddaWC.TMpercent,1)
when ddaWC.SchedPercent is null
then 1 end end EffectiveMod
which is a bit more readable... (check the logic though)

Concatenating multiple CASE statements into one alias

After some previous help on how to approach a problem I am having with some legacy code, it seems like the best approach for my issue is to concatenate case statements to return a value I can parse out in PHP.
I am trying to do something like this, but it is returning many rows, and eventually getting this error:
Maximum stored procedure, function, trigger, or view nesting level
exceeded (limit 32).
SELECT org.org_id,
org.org_name_1,
Datename(YEAR, member.enroll_date) AS enroll_year,
Max(CASE
WHEN board.member_from IS NULL THEN 0
ELSE 1
END) AS board_member,
CASE
WHEN ( org.delete_reason = 'OUT'
AND org.org_delete_flag = 'Y'
AND org.org_status_flag = 'C' ) THEN 'out_of_business|'
ELSE ''
END + CASE
WHEN ( stat.carrier = 'BS'
AND stat.status_id IS NOT NULL
AND stat.termination_date IS NULL
AND stat.flat_dues > 0 ) THEN 'insurance_member|'
ELSE ''
END + CASE
WHEN ( stat.carrier = 'BS'
AND stat.status_id IS NOT NULL
AND stat.termination_date IS NULL
AND stat.flat_dues = 0
AND member.status_flag IN( 'C', 'P' ) ) THEN 'insurance_product|'
ELSE ''
END + CASE
WHEN ( member.enroll_date IS NOT NULL
AND member.status_flag NOT IN( 'C', 'P' ) ) THEN 'member_since|'
ELSE ''
END + CASE
WHEN ( org.org_relationship_parent = 'Y'
AND org.dues_category = 'MBR'
AND org.org_status_flag = 'R' ) THEN 'subsidiary_member|'
ELSE ''
END + CASE
WHEN ( org.org_misc_data_9 = 'PAC' ) THEN 'pac|'
ELSE ''
END + CASE
WHEN ( org.dues_category = 'PART' ) THEN 'partner_member|'
ELSE ''
END + CASE
WHEN ( org.dues_category = 'FREE'
AND org.org_status_flag = 'P' ) THEN 'associate_member|'
ELSE ''
END
--ELSE 'non_member'
--END
AS org_status,
60 AS expires_in,
CASE
WHEN stat.dues_type = 'M' THEN
CASE
WHEN ( stat.termination_date IS NULL ) THEN ( stat.flat_dues )
ELSE 0
END
ELSE
CASE
WHEN ( member.payments = 0 ) THEN member.dues_billed_annual
ELSE member.payments
END
END AS dues_level,
CASE
WHEN ( org.affiliate_code = 'PCCE'
AND org.dues_category = 'MBR'
AND org.org_status_flag = 'R' ) THEN 1
ELSE 0
END AS pcce_membr,
-- '$'+CONVERT(VARCHAR,#dues) AS dues_level,
Ltrim(#product_level) AS product_level,
Ltrim(#involve_level) AS involvement_level
FROM organiz AS org
LEFT JOIN affilbil AS member
ON member.status_id = org.org_id
AND member.dues_category = 'MBR'
LEFT JOIN individu AS ind
ON ind.org_id = org.org_id
LEFT JOIN commembr AS board
ON board.status_id = ind.ind_id
AND board.committee_code = '5'
AND board.member_to IS NULL
LEFT JOIN statinsmorn AS stat
ON stat.status_id = org.org_id
AND stat.carrier = 'BS'
AND stat.planz = 'PCI'
WHERE org.org_id = #org_id
GROUP BY org.org_id,
org.org_name_1,
member.enroll_date,
org.delete_reason,
org.org_status_flag,
org.org_delete_flag,
stat.status_id,
stat.flat_dues,
stat.dues_type,
stat.termination_date,
org.org_misc_data_9,
org_relationship_parent,
org.dues_category,
member.status_flag,
member.dues_billed_annual,
member.payments,
stat.carrier,
org.Affiliate_Code
Well, this is embarrassing.
When I was making my changes to the stored procedure, I had inadvertently placed a call to the same procedure at the bottom. So I was recursively calling the same procedure over and over again. DOH.

Doctrine Set Case When

Is it possible to write in Doctrine the following SQL query?
UPDATE Inventory
SET
a = CASE WHEN a=id THEN NULL ELSE a END,
b = CASE WHEN b=id THEN NULL ELSE b END,
c = CASE WHEN c=id THEN NULL ELSE c END,
d = CASE WHEN d=id THEN NULL ELSE d END,
e = CASE WHEN e=id THEN NULL ELSE e END,
f = CASE WHEN f=id THEN NULL ELSE f END,
g = CASE WHEN g=id THEN NULL ELSE g END,
h = CASE WHEN h=id THEN NULL ELSE h END,
i = CASE WHEN i=id THEN NULL ELSE i END,
j = CASE WHEN j=id THEN NULL ELSE j END,
k = CASE WHEN k=id THEN NULL ELSE k END
WHERE userid=uid;
Nope, the CASE WHEN statement isn't supported in Doctrine - you could try using RAW SQL though ....