CarolaV
CarolaV

Reputation: 41

Nullif - using in Coldfusion

Looking for a little help with this code. Without posting the entire file which is way to big I just need a little help with using Nullif in Coldfusion.

I could I guess use it in my SQL statment, but for the sake of learning I am wondering if it can be used when setting variables as follows :-

The code doesn't throw any errors but I'd like to know where I would place the 0 after the Nullif.

<cfif AE_C NEQ 0>
    <cfset AE_P=AE_T/AE_C>
    <cfset AE_A=AE/AE_C*100>
    <cfset AE_B = AE-AE_C/H8*H9>
    <cfset AE_D=AE/H9*H8> 
<cfelse>
    <cfset AE_P=ISNULL(AE_T/NULLIF(AE_C))>
    <cfset AE_A=ISNULL(AE/NULLIF(AE_C*100))>
    <cfset AE_B=ISNULL(AE-AE_C/NULLIF(H8*H9))>
    <cfset AE_D=ISNULL(AE/NULLIF(H9*H8))>
</cfif>

Hoping it can be done this way.

Upvotes: 0

Views: 606

Answers (3)

CarolaV
CarolaV

Reputation: 41

This is some code that was written by Ben Nadel that I've found to resolve the error, perhaps someone can assist me in how I would implement it as I just can't get my head around it.

<!---
Do SQL division with divide-by-zero protection. But this,
time, let's provide a default value if the division is
not valid.
--->
<cfquery name="qDivision" datasource="#REQUEST.DSN.Source#">
SELECT
    (
        ISNULL(
            (45 / NULLIF( 0, 0 )),
            0
        )
    ) AS value
  ;
</cfquery>

<!--- Output resulting value. --->
[ #qDivision.value# ]

Upvotes: 1

Shawn
Shawn

Reputation: 4786

This is more a comment than an answer. See RRK's answer about NULLIF not being a valid ColdFusion function and ISNULL() hiding an error.

My comment is more about the logic of your operation. You don't need to do some of the steps in your <CFELSE>

Original:

<cfif AE_C NEQ 0>
    <cfset AE_P=AE_T/AE_C>
    <cfset AE_A=AE/AE_C*100>
    <cfset AE_B = AE-AE_C/H8*H9>
    <cfset AE_D=AE/H9*H8> 
<cfelse>
    <cfset AE_P=ISNULL(AE_T/NULLIF(AE_C))>
    <cfset AE_A=ISNULL(AE/NULLIF(AE_C*100))>
    <cfset AE_B=ISNULL(AE-AE_C/NULLIF(H8*H9))>
    <cfset AE_D=ISNULL(AE/NULLIF(H9*H8))>
</cfif>

I'm assuming you're using the NULLIF() to prevent divide by zero error.

First, in the languages I'm familiar with, NULLIF() requires two arguments: NULLIF(a,b) so that if a is not equal to b, it will return a, otherwise it will return NULL.

That said, your cfif says that if AE_C is not 0 then do x, else do y. I'm assuming it should be <cfset AE_P=ISNULL(AE_T/NULLIF(AE_C,0))>. If you extrapolate that out, you'd get AE_T/NULLIF(0,0) == AE_T/NULL == NULL. So you can just short-circuit that block and just set AE_P=NULL. But you also have the ISNULL() function around that, so that will always be true also. And ISNULL() (except in ColdFusion) also takes 2 arguments. In CF, it returns TRUE/FALSE (or YES/NO to be pedantic). So now you've essentially done <cfset AE_P = YES/TRUE>. I'm guessing that wasn't your original intent. So ISNULL() probably isn't appropriate here. In SQL, ISNULL(a,b) would mean that if a is NULL, return b. So (in SQL) you could essentially do AE_P = ISNULL(x,0) and that would mean that if AE_C was 0, rather than getting the divide by zero error, you could just set AE_P = 0.

TLDR; There isn't a NULLIF() function in ColdFusion, so if you're trying to prevent the div0 errors, you'll have to either do it in your SQL or modify your ColdFusion sets:

<cfif AE_C NEQ 0>
    <cfset AE_P=AE_T/AE_C>
    <cfset AE_A=AE/AE_C*100>
<cfelse>
    <cfset AE_P=0>
    <cfset AE_A=0>
</cfif>

I don't know the flow of your code, so I don't know how H8 and H9 are affected by AE_C, so you may have to check those for 0 also.

But, I'd still go back to my usual belief that if these calculations are used in SQL and not really in code, then they should be done in SQL rather than being passed out to the app server and then back to the SQL. Again, though, I don't know what your code is doing, so it may be more appropriate to have those calcs in code.

Upvotes: 0

rrk
rrk

Reputation: 15875

IMPORTANT: Your code is not showing any error because ISNULL is masking the error.


Also NULLIF is not a valid ColdFusion function. I believe the reason why there is no error in your page because, ColdFusion ISNULL() function seems to be a very versatile one and showing some undocumented characteristics. ISNULL() does not return an error even if the expression inside it is defined or not if the expression is syntactically valid.

eg.

ISNULL(AE_T/NULLIF(AE_C)) // No error because AE_T/NULLIF(AE_C) is a valid statement.

What you could do as an alternative is the following.

The following is a bit hacky, but you can check out the function val(). It will return 0 for any string that is not a number (check the doc for more details).

NULLIF(AE_C) becomes val(AE_C).

<cfset AE_P=ISNULL(AE_T/val(AE_C))>

Still if the val() return 0, then the output of ISNULL() will be YES, because division by 0 throws error.

Upvotes: 1

Related Questions