2016-03-01 33 views
1

序言:所以我们有一些工作的应用程序需要转移到新的服务器上,因为我们正在退役一个较旧的应用程序,因此我不得不安装一个新的CF实例。Coldfusion - 试图通过cfloop查询时发生复杂对象错误。版本差异?

此应用程序在运行ColdFusion版本“9,0,0,251028”标准版(通过ColdFusion管理员)的旧服务器上正常工作。

在较新的服务器上,我使用的是CF 2016版本2016.0.0.298074开发者版(这是第一个弹出的谷歌搜索,所以我去了它)。

现在问题:有一段代码给出一个错误,指出:

Complex对象类型不能被转换为简单的值。

表达式请求变量或中间表达式结果作为一个简单值。但是,结果不能转换为简单的值。简单值是字符串,数字,布尔值和日期/时间值。查询,数组和COM对象是复杂值的示例。 错误的最可能原因是您尝试使用复杂值作为简单值。例如,您尝试在cfif标记中使用查询变量。在G中发生

错误:/Gumbo/components/modules/resource/ResourceAdmin.cfc:线282 选自G调用:/Gumbo/admin/modules/resource/action.cfm:线34 选自G调用: /Gumbo/admin/action.cfm:行19

281 cfloop query="getseq"> 
282 <cfif getseq.resourceCategoryID IS temp><cfset newseq = getseq.displaySeq ><cfbreak></cfif> 
283 </cfloop> 

出错行是282.有问题的代码:

<cfloop query="getseq"> 
     <cfif getseq.resourceCategoryID IS temp><cfset newseq = getseq.displaySeq ><cfbreak></cfif> 
</cfloop> 

从我的研究,我已经指出,显然没有按CFLOOP不适用于查询一些ColdFusion版本的参数,但是我不明白的是为什么NEWER版本会导致我这个错误。

所以我的问题是:

  1. 有没有办法以某种方式重新获得CF的此旧版本?请记住,我的旧计算机上有CF9源文件夹,但我不确定是否有办法将原始文件移动或手动安装,或者手动安装它。它可以像将较旧的源文件复制到较新的服务器上的新CF源一样简单吗?

  2. 什么是改变上述代码的简单替代方法?我对CF完全不熟悉,因为这是我在接受这份工作时继承的一个较老的项目。我更喜欢在较新的系统上获得确切的版本,但更改代码是唯一可行的选择。

任何洞察力将不胜感激。

编辑:

这里是整个违规功能:

<cffunction name="updateResource" access="public" output="false" displayname="Update a Resource">  
    <cfset VARIABLES.dateUpdated=DateAdd("d", 0, arguments.dateUpdated)>  

    <cfquery datasource="#this.datasource#"> 
     update md_rlm_resource 
     set published=<cfqueryparam cfsqltype="cf_sql_tinyint" value="#arguments.published#">, 
      resourceName=<cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.resourceName#">, 
      resourceNumber=<cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.resourceNumber#">, 
      resourceAuthor=<cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.resourceAuthor#">, 
      resourceFile=<cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.resourceFile#">, 
      dateUpdated=<cfqueryparam cfsqltype="cf_sql_timestamp" value="#VARIABLES.dateUpdated#">, 
      shortDescription=<cfqueryparam cfsqltype="cf_sql_longvarchar" value="#arguments.shortDescription#"> 
     where resourceID=<cfqueryparam value="#arguments.resourceID#" cfsqltype="cf_sql_integer"> 
    </cfquery>  

    <cfquery name="getseq" datasource="#this.datasource#"> 
     select displaySeq, resourceCategoryID 
     from md_rlm_resourcecategoryrel 
     where resourceID=<cfqueryparam value="#arguments.resourceID#" cfsqltype="cf_sql_integer"> 
    </cfquery> 

    <cfquery datasource="#this.datasource#"> 
     delete from md_rlm_resourcecategoryrel 
     where resourceID=<cfqueryparam value="#arguments.resourceID#" cfsqltype="cf_sql_integer"> 
    </cfquery> 

    <cfif IsDefined("arguments.resourceCategoryIDs")> 
     <cfset resourceCategoryID = ArrayNew(1)> 
     <cfset resourceCategoryID = ListToArray(arguments.resourceCategoryIDs)> 

     <cfif #ListLen(arguments.resourceCategoryIDs)# gt 1> 
     <cfset tmp1 = #ArrayLen(resourceCategoryID)#> 
     <cfelse> 
     <cfset tmp1 = "1"> 
     </cfif> 

     <cfloop INDEX="idx" FROM="1" TO="#tmp1#">  
     <cfset newseq = 1> 

     <cfif #tmp1# gt 1> 
      <cfset temp=resourceCategoryID[idx]> 
     <cfelse> 
      <cfset temp=resourceCategoryID>   
     </cfif> 

     <cfloop query="getseq"> 
      <cfif getseq.resourceCategoryID IS temp><cfset newseq = getseq.displaySeq ><cfbreak></cfif> 
     </cfloop> 

     <cfquery datasource="#this.datasource#"> 
      insert into md_rlm_resourcecategoryrel 
      (resourceCategoryID, resourceID, displaySeq) 
      values 
      (
      <cfif #tmp1# gt 1> 
      <cfqueryparam CFSQLTYPE="cf_sql_integer" VALUE="#resourceCategoryID[idx]#">, 
      <cfelse> 
      <cfqueryparam CFSQLTYPE="cf_sql_integer" VALUE="#resourceCategoryID#">, 
      </cfif>  
      <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.resourceID#">, 
      <cfqueryparam cfsqltype="cf_sql_float" value="#newseq#">) 
     </cfquery> 
     </cfloop> 
    </cfif> 

    <cfquery datasource="#this.datasource#"> 
    DELETE FROM md_rlm_resourceregionrel 
    WHERE resourceID=<cfqueryparam value="#arguments.resourceid#" cfsqltype="cf_sql_integer"> 
    </cfquery> 

    <cfloop index="regionele" list="#arguments.regionID#" delimiters=","> 
     <cfquery datasource="#this.datasource#"> 
     INSERT INTO md_rlm_resourceregionrel (resourceID, regionID) 
     VALUES (<cfqueryparam value="#arguments.resourceid#" cfsqltype="cf_sql_integer">, #regionele#) 
     </cfquery> 
    </cfloop> 
</cffunction> 
+1

您可以在cfrepo上找到归档的ColdFusion版本http://www.gpickin.com/cfrepo/至于你的错误什么是'temp'?如果你需要看看变量是什么,那么你可以通过'cfdump'来检查它。 –

+0

temp是一个resourceCategoryID,从另一个数据库表中获取并进行比较,以确保ID与我所知道的相同。这对我的理解没有影响到这个问题,因为它在其他版本上运行良好。 现在检出回购,感谢推荐! –

+0

我们正处于同一迁移过程中(CF 9到2016)。我建议你专注于重构你的代码库来解决这样的差异问题,而不是坚持使用旧版本的CF.你是否抛出查询每一行的内容,并为循环的每次迭代抛弃“temp”的值?您可能有错误的数据,到2016年会有不同的解释。我们遇到了像CF 9运行的无效函数语法,但不是2016年。我们有一个项目专门用于解决这些类型的代码差异,然后再发布2016生产。 –

回答

1

从这:

<cfset resourceCategoryID = ListToArray(arguments.resourceCategoryIDs)> 
... 
<cfif #tmp1# gt 1> 
    <cfset temp=resourceCategoryID[idx]> 
<cfelse> 
    <cfset temp=resourceCategoryID><!--- temp is now an array --->   
</cfif> 

temp(可怕变量名,顺便说一句)可能是一个数组。

后来你这样做:

<cfif getseq.resourceCategoryID IS temp> 

不能与IS操作比较数组:IS比较简单的值。这就是你看到错误的原因。

顺便说一句,你不是var-你的代码中的任何变量,这是相当糟糕的形式,并有可能在代码中出现“意外行为”。

+0

谢谢你的解释!我继承了这个代码,我同意这个表单很糟糕,加上我不知道coldfusion,所以这是一个很难调试的问题。我正在寻找解决方案来比较复杂的数据类型,我看到有一个EQUAL和EQ命令,它们中的任何一个都适合数组吗?或者我将不得不将数组转换为列表然后进行比较? 此外,为什么你怀疑这个错误是不是与旧的CF版本,如9? –

+0

'EQ'和'EQUAL'和'IS'都是相同的操作符。至于它为什么可以在旧版本上工作?不确定。也许 - 出于某种原因,我没有访问代码 - 它总是击中if语句的“true”分支。你*可能*能够使用'oneArray.equals(anotherArray)'比较两个数组? (ref:https://docs.oracle.com/javase/8/docs/api/java/util/Vector.html#equals-java.lang.Object -...) –

+0

虽然'equals(...) '*可以*工作,这可能不是IMO的最佳选择。原因是它比典型的CF比较更敏感。通常'equals()'也考虑区分大小写和数值数据类型。例如,元素“123”将被认为不同于“val(123)”。 – Leigh