2016-03-01 13 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