这个问题已经困扰我一个多星期了,我迫切需要一个解决方案。
我一直在为我们基于 ColdFusion 的 CMS 系统构建一个模块,它允许用户构建一个包含一系列类(class)的类(class)。顺序表示先决条件,例如:
一级 2级 3级 4类
第 1 类是序列中的第一个类,需要才能继续第 2 类,等等...
我已经成功地允许用户创建上述类(class),但是编辑它们是个窍门。在我的编辑界面中,序列显示在 CFSELECT 列表框中。用户可以在列表上执行 4 个操作:上移、下移、删除和添加。这使用户能够完全操纵列表。
问题:
我们的数据库真的很旧,事实上我们的整个 CMS 系统是在 99 年构建的,所以我们处理的是一个相当过时且设计不佳的数据集。序列存储如下:
每门类(class)都存储在一个名为 moodle_programs 的表中。它的唯一标识符是自动递增的 mpID 列。
序列中的每个类都存储在一个名为 moodle_course 的表中,其唯一标识符是自动递增的 mcID。
我们将关系存储在名为 moodle_relationships 的查找表中,该表具有以下结构:
- mrID - 自动递增
- mpID - 类(class) ID
- mcID - 类 ID
- 活跃 - 是/否
- predecessor - 序列中的第一行设置为0,其余为上一行的mrID
moodle_relationships 中的一行代表序列中的一个类。
这意味着我的算法基本上需要考虑以下几点:
如果当前类(class)列表 = 该类(class)的当前行数 然后用正确的值覆盖 mcID 否则如果当前类(class)列表<该类(class)的当前行数 然后覆盖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>
从我所看到的情况来看,它是有效的,除了一个流氓错误,在更新表格并返回编辑类(class)之后,有时我注意到一个类已更改为另一个类,更具体地说,一个类已经存在于序列中创建一个副本。
我认为这与我在主循环中的比较运算符有关,虽然我看不到它在哪里,但对行的考虑是重叠的。
有什么想法吗?
最佳答案
有很多方法可以做到这一点。一种方法是删除所有现有记录并输入一个新记录集。
<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>
注意:因为涉及删除,请确保在测试数据库上运行此代码。
关于mysql - 根据有序列表中的更改修改数据库表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15215922/