【问题标题】:Nullif - using in ColdfusionNullif - 在 Coldfusion 中使用
【发布时间】:2018-08-03 11:17:15
【问题描述】:

寻求有关此代码的一些帮助。在不发布太大的整个文件的情况下,我只需要一点帮助就可以在 Coldfusion 中使用 Nullif。

我猜想在我的 SQL 语句中使用它,但为了学习,我想知道在设置变量时是否可以使用它:-

代码没有抛出任何错误,但我想知道在 Nullif 之后将 0 放在哪里。

<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>

希望可以这样。

【问题讨论】:

  • 如果您将0 设置为null,您将得到一个错误,因为除以0 将是一个错误。
  • 如果你能提供你正在寻找的输出的大纲,那就太好了。
  • 上面的代码只是一组 20 奇数。当我们将零除以 4 而不抛出异常时,我们需要计算显示 0.00。目前,对于显然被计为 1 的每个值,我都收到了 1 的计算结果。我发现了一段由 Ben Nadel 编写的关于处理 Nullif() 的代码,该代码在 SQL 语句中使用时会正确设置所有值这样您就不会收到错误。我只是不知道如何实现它。我会在下面贴出来。也许这就是答案?
  • 0/1 是有效的数学。 42/null 也是如此。当您尝试将底部数字设为 0 (1/0) 时会引发错误。我认为您遇到的问题是隐式类型转换。 9/2 将返回 5,但 9.0/2 将返回 4.5。您必须将每个操作中的第一个数字设为小数,以使其余数字也强制转换为小数。

标签: coldfusion nullif


【解决方案1】:

重要提示:您的代码没有显示任何错误,因为ISNULL 正在掩盖错误。


另外,NULLIF 不是有效的 ColdFusion 函数。我相信您的页面没有错误的原因是,ColdFusion ISNULL() 函数似乎是一个非常通用的函数,并且显示出一些未记录的特征。 ISNULL() 不会返回错误,即使其中的表达式已定义或表达式在语法上有效。

例如。

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

您可以做的替代方法如下。

以下内容有点hacky,但您可以查看函数val()。对于任何不是数字的字符串,它将返回 0(有关详细信息,请查看文档)。

NULLIF(AE_C) 变为 val(AE_C)

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

如果val() 返回0,那么ISNULL() 的输出将是YES,因为除以0 会引发错误。

【讨论】:

  • 我从未意识到ISNULL() 实际上会掩盖错误。 writeOutput(ISNULL(1/0))YES。 :-/ 我很幸运,我没有通过“成功完成”div0 操作在宇宙结构上撕开一个洞。
  • @Shawn 确实。 ColdFusion 以神秘的方式工作。哈哈
  • 考虑到 CF 2018 只是添加了真正的 NULL 支持,我不太确定他们为什么会有 ISNULL()。 :-)
【解决方案2】:

这是由 Ben Nadel 编写的一些代码,我发现它可以解决该错误,也许有人可以帮助我如何实现它,因为我无法理解它。

<!---
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# ]

【讨论】:

  • 好吧,在这种情况下,NULLIF 的 CF 替代方案将是使用类似的东西。 Compare(a, b) EQ 0 ? '' : a
  • Ben 的代码本质上是说如果0(或您的输入)等于0,则返回NULL。这导致45/NULL。这是NULL(因为您不能对NULL 值进行数学运算)。然后ISNULL(45/NULL) 将返回第二个值,即0。不过,如果您已经知道除数将是0,我认为您不需要完成所有第二次操作。
【解决方案3】:

这更像是一个评论而不是一个答案。请参阅 RRK 关于 NULLIF 不是有效的 ColdFusion 函数和 ISNULL() 隐藏错误的回答。

我的评论更多的是关于您的操作逻辑。您无需执行&lt;CFELSE&gt; 中的某些步骤

原文:

<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>

我假设您使用NULLIF() 来防止divide by zero 错误。

首先,在我熟悉的语言中,NULLIF() 需要两个参数:NULLIF(a,b),这样如果a 不等于b,它将返回a,否则将返回@ 987654333@。

也就是说,您的 cfif 表示如果 AE_C 不是 0 则执行 x,否则执行 y。我假设它应该是&lt;cfset AE_P=ISNULL(AE_T/NULLIF(AE_C,0))&gt;。如果你推断出来,你会得到AE_T/NULLIF(0,0) == AE_T/NULL == NULL。因此,您可以将该块短路并设置AE_P=NULL。但是你也有ISNULL() 函数,所以这也总是正确的。而ISNULL()(ColdFusion 除外)也需要 2 个参数。在 CF 中,它返回 TRUE/FALSE(或 YES/NO 是迂腐的)。所以现在你基本上完成了&lt;cfset AE_P = YES/TRUE&gt;。我猜这不是你的初衷。所以ISNULL() 在这里可能不合适。在 SQL 中,ISNULL(a,b) 表示如果aNULL,则返回b。所以(在 ​​SQL 中)你基本上可以做AE_P = ISNULL(x,0),这意味着如果AE_C0,而不是得到divide by zero 错误,你可以设置AE_P = 0

TLDR; ColdFusion 中没有NULLIF() 函数,因此如果您想防止div0 错误,您必须在SQL 中执行此操作或修改您的ColdFusion 集:

<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>

我不知道你的代码流程,所以我不知道H8H9 是如何受AE_C 影响的,所以你可能还需要检查0 的那些。

但是,我仍然会回到我通常的信念,如果这些计算是在 SQL 中使用而不是在代码中使用,那么它们应该在 SQL 中完成,而不是传递给应用服务器,然后再传回SQL。不过,我不知道您的代码在做什么,因此在代码中包含这些计算可能更合适。

【讨论】:

  • trycf.com/gist/10c7c2acf73aa65b8509461702459c99/… 这显示了您最终如何将YES/NO 作为您的一些最终值。
  • 最初我尝试了简单的 cfset AE_P=0 方法,但这只是自动将所有内容设置为零。例如,我在数据库中有一个值为 0.00,然后是另一个值为 5.48。如果我从 5.48 中减去 0.00,那么我的结果是 5.48,这是我需要显示的,但是通过这种方式设置它只会显示 0.00
  • 为了得到5.48,你做了什么数学运算?另外,“AE_P=0 ... 将所有内容设置为零”是什么意思?
猜你喜欢
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-06
  • 1970-01-01
  • 2012-10-04
  • 2015-01-16
  • 2014-12-22
相关资源
最近更新 更多