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 直到到达序列的末尾,并且将所有剩余行设置为 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 类

由于我的循环只会迭代三次,它从不考虑第四个索引。

我怎样才能解决这个问题?


编辑

我自己通过创建 CFSET count = 0 来解决这个问题,然后在数据库中修改项目时 count += 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

有很多方法可以做到这一点。一种方法是删除所有现有记录并输入新记录。

<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 回答