我们可以使用ColdFusion的ArrayAppend()函数将DateTime追加到数组吗?

时间:2018-11-06 11:44:34

标签: sql sql-server coldfusion coldfusion-2016

  

错误:无法将对象类型[DateTime]强制转换为类型[Array]的值

<cfset Seniority=ArrayNew(1)>
  <CFLOOP QUERY="all_employees">
      <cfif isNull(all_employee.TimeInPositionDate) >
          <cfset ArrayAppend(Seniority,all_employee.hiredate)>
      <cfelse>
          <cfset ArrayAppend(Seniority,all_employee.TimeInPositionDate)>
      </cfif>
  </CFLOOP>

2 个答案:

答案 0 :(得分:6)

您的问题源于CFML中的variable lookup。在查询循环中时,ColdFusion将在变量作用域之前从查询作用域中拉出。由于查询中有一列也称为Seniority,因此您的代码读取的内容与ArrayAppend(all_employees.Seniority,all_employees.hiredate)相同;

更改阵列名称将解决当前的问题。

 <cfset all_employees = queryNew(
    "Id,TimeInPositionDate,Hiredate,Seniority",
    "Integer,Timestamp,Timestamp,Timestamp",
    [
        {"Id":1,"HireDate":Now(),"Seniority":Now()},
        {"Id":2,"HireDate":Now(),"TimeInPositionDate":Now(),"Seniority":Now()}
    ]
)>

<cfset arrSeniority=ArrayNew(1)>

<CFLOOP QUERY="all_employees">
    <cfif isNull(all_employees.TimeInPositionDate) >
        <cfset ArrayAppend(arrSeniority,all_employees.hiredate)>
    <cfelse>
        <cfset ArrayAppend(arrSeniority,all_employees.TimeInPositionDate)>
    </cfif>
</CFLOOP>
<cfdump var="#arrSeniority#"/>

答案 1 :(得分:2)

我仍然认为CFScript中的循环要容易得多(更不用说它看起来更干净了。无论如何,我可以将其简化为一行代码(在数组之外)创建和循环代码)。

首先,我设置了伪造的查询对象:

all_employees = QueryNew(
    "id, TimeInPositionDate, hiredate" ,
    "integer, date, date" ,
    [
        {
          id:1 ,
          TimeInPositionDate: "2018-01-01" , 
          hiredate: "2017-01-01"
        } , 
        {
          id:2 ,
          // TimeInPositionDate: Not defined, so NULL
          hiredate: "2017-02-01"

        } , 
        {
          id:3 ,
          TimeInPositionDate: "2018-03-01"
          //hiredate: Not defined, so NULL
         } ,
        {
          id:4 
          //TimeInPositionDate: Not defined, so NULL
          //hiredate: Not defined, so NULL
         } 
    ]
);

我已经创建了3行。 1个完整的行,1个仅包含TimeInPositionDate,1个仅包含hiredate,1个都不包含。 ColdFusion对待null的方式一直有点奇怪,并且它并不总是与SQL查询紧密结合。在我们的伪查询中,我们只是没有定义要成为null的行。

接下来,我创建我的数组:

Seniority = [] ;

我们不必使用ArrayNew()来创建数组。我们可以使用隐式表示法将其缩短。

接下来,我们在查询周围使用for/in循环将行数据附加到新数组中。

for (r in all_employees) {
    Seniority.append( len(r.TimeInPositionDate) ? r.TimeInPositionDate : r.hiredate ) ;
}

在这里,我们使用append()成员函数将其添加到我们的Seniority数组中。我们还使用三元运算来选择要添加的值。它基本上说如果该行的长度为TimeInPositionDate,则我们使用第一个条件(TimeInPositionDate),否则我们使用hiredate

我虽然要使用猫王操作员...

Seniority2.append( q.TimeInPositionDate ?: q.hiredate ) ;

...,但是由于查询可能返回q.TimeInPositionDate=""而不是实际的null值,因此第一个值是技术上定义的并被选择。可以在真正的null上使用,但是空字符串不是null

您可能还可以使用each()或其他一些循环函数来遍历您的查询对象,但是我发现for/in循环在这种情况下通常会更快。您必须进行测试。

您可以在以下位置玩完整的游戏:

https://cffiddle.org/app/file?filepath=de107907-234c-4df8-9386-02a288e53313/fdf21791-6cc4-4c55-b923-ad7726efa8ee/b3b6b906-8e3a-4f6b-9ec8-65845efc40f1.cfm

编辑NULL个非常有趣。如果我们使用Java,则可以从查询中获得实际的null值,而不是经过cfquery转换的空字符串,并表明Elvis仍在建筑物中。

all_employees.getDate("TimeInPositionDate") ?: all_employees.getDate("hiredate") ) ;

由于Java在查询中的getDate()将获得实际值并可以处理null,因此对于TimeInPositionDatenull的行,它可以正确选择第二个选项。就是说,尽管我很欣赏Java和ColdFusion的集成,但在这种情况下我不建议这样做。它正在将Java大量混合到CF中,并且在演示之前没有必要。