如何在查询的 Coldfusion 查询中测试 null/空字符串?

问题描述 投票:0回答:3

我一直在网上寻找解决方案,但没有找到。我在 Coldfusion 查询中有一个列“date_hired”。如果我对查询进行 cfdump,如果是日期,则显示为日期;如果不是,则显示为 [空字符串]。查询有8条记录;有些有 date_hired 日期,有些则没有。如果我尝试对此结果集执行 q of q 操作:

SELECT date_hired
    FROM myQuery
    WHERE date_hired = ''

我收到一条错误消息:执行 = 时出现比较异常。 不支持的类型比较异常: = 运算符不支持以下类型之间的比较: 左侧表达式类型=“NULL”。 右侧表达式类型=“STRING”。

好的,所以我将查询更改为:

SELECT date_hired
    FROM myQuery
    WHERE date_hired IS NOT NULL

但它返回所有 8 行,甚至是 cfdump 中 date_hired 为 [空字符串] 的行。同样,如果我将 where 子句更改为“where date_hired IS NULL”,我会返回 0 行,甚至不会返回 [空字符串] 行。

我很茫然。 ISNULL() 和 LEN() 不能在 q of q 中使用。幸运的是,如果我对查询执行 cfloop 并输出 isDate(date_hired),它确实会在应该返回 true 的地方返回 true,在应该返回 false 的地方返回 false。因此,我可以对查询进行 cfloop 并即时构建另一个查询,但这似乎是一种迂回的方式来完成一些不应该困难的事情。我可以在 where 子句中使用一些可以在这里使用的条件吗?谢谢-CM

sql coldfusion qoq
3个回答
4
投票

感谢亚历克斯的回复 - 我终于明白了。在本例中,我的查询是通过 cfquery 拉取的,然后我稍后使用 queryAddColumn() 添加一些列。其中一列是 date_hired。如果我尝试走 cfloop 路线,无论我将该列的值设置为什么(日期或字符串),CF 都会将其保留为 NULL 类型(并且不适用于 IS NULL/IS NOT NULL)。因此,经过进一步的研究,我尝试在 where 子句中使用 Cast() 函数:

<cfquery name="numberHired" dbtype="query">
        select count(*)
        from myQuery
        where CAST(date_hired AS varchar) <> '' 
  </cfquery>

它就像一个魅力。


1
投票

这是另一种可能运行得更快的方法。 它利用了查询列可以被视为数组的事实。

<cfquery name="dbQuery" datasource="oracleDB">
select trunc(sysdate) theDate
from dual
union
select null theDate
from dual
union
select trunc(sysdate - 1) theDate
from dual
</cfquery>

请注意,有两个值不为空。 这个:

<cfdump var="#Listlen(ArrayToList(dbQuery['theDate']))#">

返回 2,这是您要查找的数字。

这种方法可能比使用 Q of Q 更有效。但是,Q of Q 方法更具可读性,这也很重要。


0
投票

这就是我处理来自电子表格的空行的方式。上面提到的答案对我来说并没有真正起作用,因此必须提出我自己的答案。我们在处理所有批量文件上传时使用它。

    <!--- NOTE: 
        Any empty rows captured should be ignored.
        We need to wrap any special key words in square brackets ex: [Year] or [local] when performing QoQs 
    --->
    <cfset local.sColList = arguments.columnsList />
    <cfloop list="local,Year" index="local.sKeyWord">
        <cfif ListFindNoCase(local.sColList,local.sKeyWord) GT 0>
            <cfset local.sColList = replaceNoCase(local.sColList, local.sKeyWord, "[#local.sKeyWord#]") />
        </cfif>
    </cfloop>
    <!--- Do a QoQ as the best performant solution over loops to remove the empty rows. --->
    <cfset local.sWhereClause = "" />
    <cfloop list="#local.sColList#" index="local.sCol">
        <cfset local.sWhereClause &= "(" & local.sCol & " <> '' AND " & local.sCol & " IS NOT NULL) OR " />
    </cfloop>
    <!--- Appending the below condition to handle the extra "OR" that gets appended above after the last list element --->
    <cfset local.sWhereClause &= "1 = 0" />
    <!--- Performing a Query of Query to discard the empty rows where all columns were empty --->
    <cfquery name="local.qSSData" dbtype="query">
        SELECT #local.sColList# FROM arguments.spreadSheetQuery
        WHERE #local.sWhereClause#
    </cfquery>

    <cfreturn local.qSSData />
</cffunction>
© www.soinside.com 2019 - 2024. All rights reserved.