2013-03-05 85 views
1

此問題一直困擾着我一個多星期,現在我迫切需要一個解決方案。根據有序列表中的更改修改數據庫表

我一直在爲我們基於ColdFusion的CMS系統建立一個模塊,它允許用戶建立一個具有一系列類的課程。序列順序表示的先決條件,所以例如:

1類 2類 第3類 第4類

1級是第一類中的序列中,並且需要以前進到2級等...

我已經成功地允許用戶創建所述課程,但是編輯它們是個訣竅。在我的編輯界面中,序列用CFSELECT列表框表示。用戶可以在列表上執行4個操作:向上移動,向下移動,刪除和添加。這使用戶能夠完全操縱列表。

問題:

我們的數據庫是真的老了,其實我們整個的CMS系統,建於99年,從而用一個相當處理過時,有點設計不當的數據集。序列存儲如下:

每門課程存儲在一個名爲moodle_programs的表中。其唯一標識符是自動增量的列mpID。

序列中的每個類都存儲在一個名爲moodle_course的表中,其唯一標識符是mcID,它是一個自動增量。

我們保存它具有以下結構,稱爲moodle_relationships在查找表的關係:

  • MRID - 自動遞增
  • MPID - 進程ID
  • MCID - 類ID
  • 活躍 - 是/否
  • 前身 - 序列中的第一行設置爲0,其餘爲前一行的mrID

moodle_relationships中的一行表示序列中的一個類。

這意味着,我的算法基本上需要考慮以下幾點:

如果當前類列表=該課程 當前的行數,然後用正確的價值觀 否則覆蓋MCID如果當前類列表<達到該課程 然後覆蓋MCID直到序列的結束的當前的行數,並設置所有剩餘行到活性=「N」

這是通過此算法來完成:

//comma deliminated list of mcIds before edit 
<CFSET preclasses = listToArray(#PREsectionOrder#, ",")> 
// number of classes 
<CFSET numpreClasses = ArrayLen(#preclasses#)> 

//comma deliminated list of mcIds after edit 
<CFSET classes = listToArray(#sectionOrder#, ",")> 
//number of classes 
<CFSET numClasses = ArrayLen(#classes#)> 

<!--- Modify moodle_relationships ---> 
<CFQUERY NAME="Course_seq" DATASOURCE="#CMS_SD#"> 
SELECT * 
    FROM moodle_relationships 
    WHERE mpID = #URL.id# 
</CFQUERY> 

<CFSET row = 0> 

<CFLOOP QUERY="Course_seq"> 

<CFSET row = #Course_seq.CurrentRow#> 

<CFQUERY NAME="relation" DATASOURCE="#CMS_SD#"> 
     SELECT * 
     FROM moodle_relationships 
     WHERE mrID=#Course_seq.mrID# 
    </CFQUERY> 

    <CFIF #row# LTE #numClasses#> 
     <!--Change Classes--> 
     <CFQUERY NAME="change" DATASOURCE="#CMS_SD#"> 
     UPDATE moodle_relationships 
     SET mcID='#classes[row]#', active='Y' 
     WHERE mrID=#relation.mrID# 
     </CFQUERY> 
    <CFELSEIF (#row# GT #numClasses#) AND (#row# LTE #numpreClasses#)> 
     <!--Set to N--> 
     <CFQUERY NAME="set" DATASOURCE="#CMS_SD#"> 
     UPDATE moodle_relationships 
      SET active='N' 
      WHERE mrID=#relation.mrID# 
     </CFQUERY> 
    </CFIF> 
</CFLOOP> 

現在我遇到的問題是當前類的序列超過了上一個序列中的行數。我需要注意什麼時候發生這種情況,併爲其餘行執行INSERT語句。

例如:

原始序列 - 1級,2級,3級 新的序列 - 1級,2級,3級,4級

由於我的循環只會重複三次,它從不考慮第四個索引。

我該如何解決這個問題?


編輯

我設法通過創建CFSET計數= 0來解決這個問題我自己,然後計算+ = 1,當一個項目在數據庫中被修改。之後,我創建了這個代碼片段。

<CFIF #count# LT #numClasses#> 
<CFLOOP FROM="#count#" TO="#numClasses#" INDEX="i"> 
    <CFQUERY NAME="mrID" DATASOURCE="#CMS_SD#"> 
     SELECT MAX(mrID) AS MAXmrID 
     FROM moodle_relationships 
     WHERE mpID = #URL.id# 
    </CFQUERY> 
    <CFSET ID = #mrID.MAXmrID# - 1> 
    <CFQUERY NAME="new" DATASOURCE="#CMS_SD#"> 
     INSERT INTO moodle_relationships (mpID, mcID, active, predecessor) 
     VALUES ('#URL.id#', '#classes[i]#', 'Y', '#ID#') 
    </CFQUERY> 
</CFLOOP> 

它只是一個無賴的錯誤我所看到的作品,其中更新表和回到編輯課程後,有時我注意到,一類已被更改爲不同的類,更具體一個已經存在於序列中的類創建一個副本。

我想它與主循環中的比較運算符有關,雖然我無法看到它在哪裏,但對於一行的考慮重疊。

任何想法?

回答

1

有很多方法可以做到這一點。一種方法是刪除所有現有記錄並輸入新的記錄。

<cfscript> 
    /* Count the number of classes before the edit */ 
    preclasses = listToArray(PREsectionOrder, ","); 
    numpreClasses = ArrayLen(preclasses); 

    /* Count the number of classes after edit */ 
    classes = listToArray(sectionOrder, ","); 
    numClasses = ArrayLen(classes); 
</cfscript> 

<!--- Making sure we have a 'numeric' URL id ---> 
<CFPARAM name="URL.id" default="0" type="numeric" /> 

<CFSET courseId = URL.id /> 

<!--- Only continue if the courseId is not the default 0---> 
<CFIF courseId neq 0> 

    <!--- Delete the existing course and its combination classes ---> 
    <!--- Query checks for a specific course and class id ---> 
    <CFQUERY NAME="Course_seq" DATASOURCE="#CMS_SD#"> 
     DELETE 
      FROM moodle_relationships 
     WHERE mpID = <cfqueryparam cfsqltype="cf_sql_numeric" value="#courseId#" /> 
      AND mcID IN (<cfqueryparam cfsqltype="cf_sql_numeric" value="#PREsectionOrder#" list="true" separator=","/>) 
    </CFQUERY> 

    <!--- Create and Set the predecessor value to default 0---> 
    <cfset predecessorValue = 0 /> 

    <!--- Loop over the array of new classId and Insert them---> 
    <CFLOOP array="#classes#" index="newClass"> 

     <CFQUERY NAME="insertingNewCourse" DATASOURCE="#CMS_SD#"> 
      INSERT INTO moodle_relationships 
        (mpID, mcID, active, predecessor) 
      VALUES (
        <cfqueryparam cfsqltype="cf_sql_numeric" value="#courseId#" />, 
        <cfqueryparam cfsqltype="cf_sql_numeric" value="#newClass#" />, 
        <cfqueryparam cfsqltype="cf_sql_varchar" value="Y" />, 
        <cfqueryparam cfsqltype="cf_sql_numeric" value="#predecessorValue#" /> 
        ) 
     </CFQUERY> 

     <!--- The first one goes as zero. the next one shall be the just inserted classId ---> 
     <cfset predecessorValue = newClass /> 
    </CFLOOP> 

</CFIF> 

注意因爲,有刪除參與,確保在運行測試數據庫上運行此代碼。

+0

嗯我不知道爲什麼我沒有想到先刪除行。我試過這個代碼,它比我的體積小很多。然而,我忘記提及當一段關係不再存在時你刪除一個類,關係行的活動值應該設置爲'N'。 – 2013-03-05 07:58:44

+0

很高興你通過測試。要將標誌設置爲'N',您可以將刪除代碼更改爲更新。此外,投票的答案是否有幫助:) – Sanjeev 2013-03-06 02:19:44

+0

完美!我修改了標記爲'N'的查詢,它的功能就像一個魅力。再次感謝,很高興能夠結束這個項目,這是最後一個細節。 – 2013-03-06 19:41:14