1

この問題は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
  • アクティブ-Y/N
  • predecessor-シーケンスの最初の行は0に設定され、残りは前の行のmrIDに設定されます

moodle_relationshipsの行は、シーケンス内の1つのクラスを表します。

これは、私のアルゴリズムが基本的に次のことを考慮する必要があることを意味します。

現在のクラスリスト=そのコースの現在の行数の場合次にmcIDを正しい値で上書きしますそれ以外の場合現在のクラスリストが<そのコースの現在の行数の場合次にシーケンスの終わりに達するまでmcIDを上書きします残りのすべての行をactive='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

私のループは3回しか繰り返されないため、4番目のインデックスは考慮されません。

どうすればこれを修正できますか?


編集

CFSET count = 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>

テーブルを更新してコースの編集に戻った後、あるクラスが別のクラスに変更されていることに気付くことがあります。具体的には、シーケンスにすでに存在するクラスが重複を作成していることに気付くことがあります。 。

行の考慮事項が重複しているメインループの比較演算子に関係していると思いますが、それがどこにあるかはわかりません。

何か案は?

4

1 に答える 1

1

これを行うには多くの方法があります。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>

注意削除が含まれているため、このコードをテストデータベースで実行してください。

于 2013-03-05T07:33:27.183 に答える