请选择 进入手机版 | 继续访问电脑版
收藏本站腾讯微博新浪微博
点点网模板设计大赛 phpchina

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 用悬赏 三天解决问题 解决访问速度慢 论坛支持农历生日 - 给官方提建议

论坛活动及任务 归纳网站最新活动 地图任务 邮件更新任务:保护帐号安全

积分换实物,来参加蓝色理想积分兑换吧! 联系招聘客服 蓝色理想帮你找工作! 万元奖励等你拿——点点网模板设计大赛

查看: 51629|回复: 49

[asp] [ASP]无限级分类的简单算法实现及代码重点讲解。 [复制链接]

萧萧小雨 楼主

娃哈哈.COM

荣誉管理

帖子
14172
体力
34824
威望
62
居住地
天津市 南开区
发表于 2005-4-7 11:11:00 |显示全部楼层
一、前言
        很多情况下二级分类已经不能满足需要了,而网上可用的多级分类的例子实在是不好找,故有此文。
http://bbs.blueidea.com/viewthread.php?tid=1182243
大家可以先看这个,它介绍了一种超级好的算法,反正我是看不大懂呀。

二、我们要解决的问题:
1、 分类算法常常表现为树的表示和遍历问题。那么,请问:如果用数据库中的一个Table来表达树型分类,应该有几个字段?
2、 如何快速地从这个Table恢复出一棵树;
3、 如何判断某个分类是否是另一个分类的子类;
4、 如何查找某个分类的所有产品;
5、 如何生成分类所在的路径。
6、 如何新增分类;

三、递归实现的优点与缺点
        该怎么实现多级分类呢?
        估计首先想到的都是递归,实现简单,在指定节点(就是分类,下同)下添加、修改、删除节点都不是问题,
而且节点移动实现起来也不是很难,只是要注意移动目的父节点不能是当前节点的父节节点(等于没移动),也不能是当前节点的子节点(类似于window文件夹,一个文件夹是不能移动到自己的字文件夹里的)。
        但是最愁人的是搜索指定节点下的东西,怎么办?也就是上面的问题3。记住,这是要包括所有子节点的,难道还去递归吗?

四、介绍下我的简单算法(是我所用的,不是我发明的)
        以常见的商品系统为例。
        4.1 表结构
                [1]分类表,T_Sort,表结构如图一所示。其中sortPath保存的是节点路径,这是个重点。
                [2]商品表,T_Product,表结构如图二所示。
[center]图一


图二

[/center]
        4.2 算法简要说明
                [1]parentID保存的自然是节点的父节点,如果一个节点的parentID=0时,认为它是一级分类。
                [2]一个节点的sortPath为它的父节点的sortPath+自己的sortID+","。如sortID=32的节点的父节点是节点21,节点21的sortPath是"0,21,",那么节点32的sortPath就是"0,21,32,"。有点绕,看图三清楚啦。可能你想不通为啥最后要多个逗号啊,后面你就明白啦。所有节点的sortPath的左边两位都是"0,",因为它们都在根节点下。一个节点的sortPath一定包含在它的子节点的sortPath中。
[center]
图三
[/center]
        4.3 代码重点讲解。
                这里以我们要实现的功能为例讲解。
                [1]添加节点
                        <1>选择父节点,可以是根节点,或是下级所有节点(最好列出一个树型菜单让用户选择,别愁,可以实现),其实就是选择parentID。
                        <2>如果parentID=0,那么上级sortPath="0,",如果parentID<>0,那么到表T_Sort根据parentID取得上级sortPath。
                        <3>给T_Sort新增记录,sortPath=上级sortPath +新记录的sortID +","。
                        <4>范例代码见图4、图5。其中noRecord,closeRs(),showMsg(),closeConn()都是我定义的Function或Sub,它们的功能都是顾名思义的,我就不说了。注意一下,如果你用MS SQL,代码略有不同。我也很奇怪MS SQL时,addNew后,这个新的自动编号可以输出,但是和字符一连接就没有了。各位如果知道为什么,还请相告。
[center]
图四


图五
[/center]
                [2]修改节点
                        节点的属性只有一个名字而已,直接update就可以了,就不说了。
                [3]删除节点
                        <1>选择节点
                        <2>如果parentID=0,报错,根节点不能删除。
                        <3>删除该节点及所有子节点。你可能想是不是很麻烦啊,哈哈,其实我只用了一个SQL语句就搞定啦。
               
  1. (Access)sql="delete from T_Sort where Instr(sortPath,',"&parentID&",')>0"
复制代码

               
  1. (MS SQL)sql="delete from T_Sort where CHARINDEX(',"&parentID&",',sortPath)>0"
复制代码

                        本算法的精华就在这里啦,仔细想想吧,sortPath最后那个逗号的作用也在这里啦。
                        <4>删除上述所有节点下的商品。同上,表名不同而已。
               
  1. (Access)sql="delete from T_Product where Instr(sortPath,',"&parentID&",')>0"
复制代码

               
  1. (MS SQL)sql="delete from T_Product where CHARINDEX(',"&parentID&",',sortPath)>0"
复制代码

                        <5>范例代码见图6。MS SQL的代码就不贴了。
[center]
图六
[/center]
                [4]移动节点
                        难点哦,睁大眼睛仔细看。
                        <1>选择要移动的节点parentID,选择目的节点toParentID(也就是把当前节点放到谁的下面)。
                        <2>如果parentID=0报错,根节点不能移动。
                        <3>如果toParentID=parentID,这是要把自己放到自己下面,报错。
                        <4>根据parentID,取得它的sortPath,我们叫它fromPath。
                        <5>如果toParentID=0,那么toPath="0,",如果toParentID<>0,取得它的sortPath,叫它toPath。
                        <6>如果toParentID等于要移动节点的父节点,不需要移动,报错。判断方法是看toPath & parentID &","是否等于fromPath。
                        <7>如果toParentID是要移动节点的子节点,不能移动,报错。判断方法是看Instr(toPath,fromPath)是否大于0。
                        <8>组合要移动节点的新sortPath,也就是newPath=toPath & parentID &","。
                        <9>更新要移动节点及其所有子节点的sortPath()。如"0,2,3,5,"移动到"0,1,"下,那么新的sortPath就是"0,1,5,"了(想想,对吧)。而"0,2,3,5,"的所有子节点的左半部分都是"0,2,3,5,",那么只要把"0,2,3,5,"替换成"0,1,5,"就行了。
               
  1. (Access)sql="update T_Sort set sortPath='"&newPath&"'+Mid(sortPath,Len('"&fromPath&"')+1) where Instr(sortPath,'"&fromPath&"')>0"
复制代码

               
  1. (MS SQL)sql="update T_Sort set sortPath=replace(sortPath,'"&fromPath&"','"&newPath&"') where CHARINDEX[('"&fromPath&"',sortPath)>0"
复制代码

                        因为Access好像没有内置repalce函数,所以麻烦了一些。
                        <10>更新要移动节点的parentID。直接update就行啦。
                        <11>商品是跟随分类走的,所以商品的parentID不用更新,只要更新它的sortPath就行了。语句同<9>,只是表名换成T_Product。
                        <12>范例代码见图7。MS SQL的代码只有上面2个SQL语句不同,不贴了。
[center]
图七
[/center]
                [5]前台分类浏览商品
                        前台一般都不会把所有类别一下子都列出来,都是分级浏览的,一层一层的看。我们要做的只是浏览一个分类时,把它的下级分类列出来。
                        <1>取直接子类别,很简单啦。
               
  1. sql="select sortID,sortName from T_Sort where parentID="&sortID
复制代码

                        就行啦。
                        <2>一般我们都会显示一个当前位置,就是分类所在的路径,怎么办呢?难道去递归查询吗?当然不,我这里用了一个小技巧。
                        浏览某一个分类的时候,我们会有一个sortID,可以根据它从T_Sort取得sortPath....不说了,大家看示范代码吧,不懂问我。
                        范例代码见图8。
[center]
图八
[/center]
                        显示的时候用
  1. <%for i=1 to UBound(myArray)
  2.         response.write "-&gt; <a href='product.asp?sortID="&myArray(i)&"'>"&getValueByID(myArray(i),nameArray)&"</a>"
  3. next%>
复制代码

                        就OK了。getValueByID是我写的一个Function,见后。
                        <3>显示该类别及其所有子类别下的所有商品。
               
  1. sql="select * from T_Product where Instr(sortPath,',"&sortID&",')>0"
复制代码

                        如果只显示该类别下的商品,那么就用parentID判断就行了。
                [6]前台检索商品
                        如果你的检索表单不包含商品类别,那么没有什么特殊的。如果有商品类别的话,也很简单,SQL的where条件里加一个
               
  1. "and Instr(sortPath,',"&sortID&",')>0"
复制代码
就行了。
                [7]后台商品添加、修改
                        添加是要选择所在的分类,这样就可以得到sortID,并能取得它的sortPath,保存到商品记录就行了。
                        修改类似。
                [8]后台商品删除
                        和分类不相关,直接根据productID删除就可。
五、附加信息
        目前还没有拆分出来的代码给大家(太麻烦),主要的东西都在上面啦。
        师傅领进门,修行在个人啦。
  1. '-----根据ID取得name的Sub-----------------
  2. Function getValueByID(sortID,inArray)
  3.         dim i
  4.         if NOT IsArray(inArray) then
  5.                 getValueByID=""
  6.                 Exit Function
  7.         end if
  8.         for i=0 to UBound(inArray,2)
  9.                 if Cstr(sortID)=Cstr(inArray(0,i)) then
  10.                         getValueByID=inArray(1,i) '返回name
  11.                         Exit Function
  12.                 end if
  13.         next
  14.         getValueByID=""
  15. End Function
复制代码
已有 1 人评分威望 收起 理由
经典论坛大妈 + 3 历史打分

总评分: 威望 + 3   查看全部评分

哇嘎嘎……
毛绒玩具的卖~~~
西部数码顶级域名注册商39元抢注!
hubro 

Hi 阿洛瓦

钻石会员

帖子
4319
体力
8857
威望
3
发表于 2005-4-7 11:56:00 |显示全部楼层
最好能把分类树生成数组,调用时就不用那麻烦,又去写一次,并且可以任意改变输出的形状
租服务器,上51IDC | [长沙]招聘:PHP经理10K/WEB前端6K/PHP开发6K

使用道具 举报

LeXRus 

没壳的小龟

荣誉管理 手机认证 

帖子
5379
体力
20999
威望
61
发表于 2005-4-7 12:38:00 |显示全部楼层
实践证明这类和"无限级"有关的任务用XSLT来做是最高效的

使用道具 举报

萧萧小雨 楼主

娃哈哈.COM

荣誉管理

帖子
14172
体力
34824
威望
62
居住地
天津市 南开区
发表于 2005-4-7 12:59:00 |显示全部楼层
哎,终于有人顶了,不枉我写一大堆字。
to Hubro:要一个全树的时候很少,也就是选择分类的时候用到。(那个我已经用一个动态取数据的树形菜单解决了,也就是没有场合用到一个全树的啦。)

to 龟龟:同意!也用过,写节点倒是不难,自动编号我也实现了(其实就是在xml里保存一个最大数,+1就是),配合xslt很简单就出来了。但关联查询是个麻烦事呀。呱呱。

哇嘎嘎……
毛绒玩具的卖~~~

使用道具 举报

LeXRus 

没壳的小龟

荣誉管理 手机认证 

帖子
5379
体力
20999
威望
61
发表于 2005-4-7 13:33:00 |显示全部楼层
请问什么是关联查询? 为什么要自动编号?
听起来你好像偿试了用xml存数据而不是sql?

我喜欢挑战XSLT难题, 有什么它不能做的说来听听

使用道具 举报

萧萧小雨 楼主

娃哈哈.COM

荣誉管理

帖子
14172
体力
34824
威望
62
居住地
天津市 南开区
发表于 2005-4-7 13:45:00 |显示全部楼层
呵呵,俺知道xslt非常非常非常……强大,俺只知道皮毛而已,

我是用xml文件直接保存目录结构的,然后每个节点的内容在数据库里,所以得有个ID来关联呀。所以我就在xml文件里保存一个maxNumber,添加节点的时候就读取它+1,然后按照这个ID保存它的内容。

现在如果数据库保存目录结构的话,问题还是生成xml的问题,还是要递归呀。

有简单的方法吗?直接用xslt配合数据库生成多极菜单。
哇嘎嘎……
毛绒玩具的卖~~~

使用道具 举报

LeXRus 

没壳的小龟

荣誉管理 手机认证 

帖子
5379
体力
20999
威望
61
发表于 2005-4-7 15:16:00 |显示全部楼层
你不是用parentID在描述记录的关系么. 我们把这些记录看成节点, 那么无非只有两种组合:
1.包含子节点的节点 和 不包含子节点的节点
2.没有父节点的节点 和 有父节点的节点
随便哪一种, 都只须写两个template就能完成所有节点的匹配了.

使用道具 举报

萧萧小雨 楼主

娃哈哈.COM

荣誉管理

帖子
14172
体力
34824
威望
62
居住地
天津市 南开区
发表于 2005-4-7 16:23:00 |显示全部楼层
嗯嗯,假装懂啦,哈哈。
那用template匹配后是输出成xml形式,还是直接就出Html啊?

那读取数据库的时候怎么读啊?具体怎么由记录集到被xslt转换?疑惑中…………

还忘小龟解惑呀…………刮呱。
哇嘎嘎……
毛绒玩具的卖~~~

使用道具 举报

LeXRus 

没壳的小龟

荣誉管理 手机认证 

帖子
5379
体力
20999
威望
61
发表于 2005-4-7 20:15:00 |显示全部楼层

使用道具 举报

萧萧小雨 楼主

娃哈哈.COM

荣誉管理

帖子
14172
体力
34824
威望
62
居住地
天津市 南开区
发表于 2005-4-8 10:35:00 |显示全部楼层
太经典了,太厉害啦。以前我只见过把树型的xml格式化的xslt,真没见过这样就格式化的,

小龟好厉害!收藏!
哇嘎嘎……
毛绒玩具的卖~~~

使用道具 举报

帖子
81
体力
111
威望
0
发表于 2005-4-8 18:43:00 |显示全部楼层
谢谢!收藏了!

使用道具 举报

帖子
81
体力
111
威望
0
发表于 2005-4-8 18:46:00 |显示全部楼层
谢谢!
收载

使用道具 举报

帖子
921
体力
3168
威望
0
居住地
天津市 南开区
发表于 2005-4-10 08:05:00 |显示全部楼层
把SORTPATH换成定长的二进制形式得是不是会更好些...?
桃花运啊桃花劫...

使用道具 举报

boat 
帖子
62
体力
355
威望
0
发表于 2006-12-31 01:46:30 |显示全部楼层

真他妈的经典,能想到这个算法的人真神!!!

真他妈的经典,能想到这个算法的人真神!!!

真的是经典的教程啊!

使用道具 举报

幸福的子弹

金牌会员 手机认证 

帖子
1921
体力
3773
威望
4
居住地
浙江省 杭州市
发表于 2006-12-31 08:23:23 |显示全部楼层

经典!

真是太好了,太帮了,都想一个人偷偷的学,哈哈
那个啥啥啥,笑一个呗~

使用道具 举报

knazar 
帖子
9
体力
21
威望
0
发表于 2007-1-5 15:53:16 |显示全部楼层
靠。
这是什么?这是什么??
告诉我这是什么!
太经典了。
这种方法我喜欢
楼主我爱你。

使用道具 举报

帖子
13
体力
10
威望
0
发表于 2007-6-15 10:29:34 |显示全部楼层
厉害,厉害。不过楼主想这个问题已经很久了。因为之前的你的一篇帖子就在讨论这个问题。这个帖子距离那个是快两年的时间呀。

使用道具 举报

帖子
13
体力
10
威望
0
发表于 2007-6-15 16:31:52 |显示全部楼层
楼主请教,用你这个设计的数据库要怎么读出树型菜单的。我想了半天了,不得要领。在线等待。

使用道具 举报

帖子
13
体力
10
威望
0
发表于 2007-6-15 16:33:31 |显示全部楼层
二年前的帖子了,都事过境迁了。楼主还看得到我的问题么?

使用道具 举报

萧萧小雨 楼主

娃哈哈.COM

荣誉管理

帖子
14172
体力
34824
威望
62
居住地
天津市 南开区
发表于 2007-6-15 16:52:38 |显示全部楼层
树型菜单一般都是客户端用JS来生成的,你要做的就是按JS的数据格式要求生成就行了。
哇嘎嘎……
毛绒玩具的卖~~~

使用道具 举报

苦寒竹

管理员

帖子
19765
体力
17915
威望
23
居住地
浙江省 金华市
发表于 2007-6-15 17:02:56 |显示全部楼层
从前年看到今年.
受益了.
搞IT的穷秀才。

使用道具 举报

帖子
13
体力
10
威望
0
发表于 2007-6-15 17:12:41 |显示全部楼层
<ul id="containerul">
  <li> 动网新闻系统
    <ul>
      <li> <a href="http://www.xmlasp.net/c49.aspx">风格模板</a>
      </li>
      <li>
        <a href="http://www.xmlasp.net/c48.aspx">使用帮助</a>
      </li>
      <li>
        <a href="http://www.xmlasp.net/c36.aspx">使用技巧</a>
      </li>
    </ul>
  </li>
  <li> 技术文章
    <ul>
      <li>
        <a href="http://www.xmlasp.net/c17.aspx">脚本技术</a>
      </li>
      <li>
        <a href="http://www.xmlasp.net/c12.aspx">Asp.net</a>
        <ul>
          <li>
            <a href="http://www.xmlasp.net/c13.aspx">C#</a>
          </li>
          <li>
            <a href="http://www.xmlasp.net/c14.aspx">Ado.net</a>
          </li>
          <li>
            <a href="http://www.xmlasp.net/c37.aspx">Xml</a>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

使用道具 举报

帖子
13
体力
10
威望
0
发表于 2007-6-15 17:13:46 |显示全部楼层
这个是js代码的显示内容的,我只读到跟目录的那些名字,下一级的名字就不知道怎么来读取了。

使用道具 举报

帖子
13
体力
10
威望
0
发表于 2007-6-15 19:59:14 |显示全部楼层
小雨,请指教下哈。

使用道具 举报

默默无痕

高级会员

帖子
230
体力
624
威望
0
发表于 2007-6-15 21:55:23 |显示全部楼层
学习一下

使用道具 举报

默默无痕

高级会员

帖子
230
体力
624
威望
0
发表于 2007-6-15 23:40:22 |显示全部楼层
学习一下

使用道具 举报

萧萧小雨 楼主

娃哈哈.COM

荣誉管理

帖子
14172
体力
34824
威望
62
居住地
天津市 南开区
发表于 2007-6-16 07:32:17 |显示全部楼层
大概这样不就行吗?

"........and Instr(sortPath,',"&sortID&",')>0"
哇嘎嘎……
毛绒玩具的卖~~~

使用道具 举报

camper 

半成品

银牌会员 手机认证 

帖子
994
体力
2642
威望
0
居住地
江苏省 苏州市
发表于 2007-11-3 10:40:28 |显示全部楼层
老帖疑问,顶下。

有个问题不太明白,就是删除节点:
==================================
[3]删除节点
                     <1>选择节点
                     <2>如果parentID=0,报错,根节点不能删除。
                     <3>删除该节点及所有子节点。你可能想是不是很麻烦啊,哈哈,其实我只用了一个SQL语句就搞定啦。

(Access)sql="delete from T_Sort where Instr(sortPath,',"&parentID&",')>0"
==================================
parentID应该是指要删除的节点的父节点的ID对吧。
举个例子,如果一个根节点ID是1,那sortpath就是0,1,,一个子节点的parentID是1,自身ID是2,那sortpath就应该是0,1,2,对吧,假设还有一个平行的子节点parentID也是1,自身ID是3,那sortpath就应该是0,1,3,,假设现在我要删除ID为2的这个节点,那么按照你的数据就应该是delete from T_sort where Instr(sortpath,',1,')>0,那不是把这三个节点都删除了吗,也就是你这个语句的作用就变成了“删除目标节点的父节点及此父节点之下的所有子节点”,我觉得应该是用delete from T_sort where Instr(sortpath,',"&id&",')>0才对吧,这个ID是指要删除的节点的ID。

不知道是不是我自己绕进去了,呵呵,望指点。。

使用道具 举报

胖大海

高级会员

帖子
755
体力
757
威望
0
居住地
山东省 青岛市
发表于 2007-11-3 13:28:41 |显示全部楼层
晕了
沉默寡言

使用道具 举报

萧萧小雨 楼主

娃哈哈.COM

荣誉管理

帖子
14172
体力
34824
威望
62
居住地
天津市 南开区
发表于 2007-11-3 15:24:45 |显示全部楼层
哦,这里的parentID就是指它本身的ID,不是父的……

干脆,我把那个文件整个贴一下,可以瞅瞅。
  1. <%@ CODEPAGE="936"%>
  2. <!--#include File="admin_session.asp" -->
  3. <!--#include File="conn.asp" -->
  4. <%
  5. myAction=trim(request("myAction"))
  6. parentID=trim(request("parentID")) '选择的类别
  7. toParentID=trim(request("toParentID")) '移动到的类别
  8. new_sortName=trim(request("new_sortName")) '新增的类别名称
  9. edit_sortName=trim(request("edit_sortName")) '修改的类别名称

  10. if parentID="" or NOT IsNumeric(parentID) then
  11.         call showMsg("请选择要操作的类别。")
  12. end if
  13. '================执行操作================
  14. select case myAction
  15. case "addSort"
  16.         if new_sortName="" or Len(new_sortName)>50 then
  17.                 call showMsg("请输入新增类别的名称(少于50字)。")
  18.         end if
  19.         '--查询父节点的路径
  20.         set rs=server.CreateObject("adodb.recordset")
  21.         sql="select * from TBL_Sort where sortID="&parentID
  22.         rs.open sql,conn,1,3
  23.         if parentID=0 then '根节点不存在,直接赋值。
  24.                 sortPath="0,"
  25.         else
  26.                 if noRecord(rs) then
  27.                         call closeRs(rs)
  28.                         call showMsg("指定类别不存在。")
  29.                 end if
  30.                 sortPath=rs("sortPath") '父节点的路径
  31.         end if
  32.         '--新增记录
  33.         rs.addNew
  34.         rs("sortName")=new_sortName
  35.         rs("parentID")=parentID
  36.         rs("sortPath")=sortPath & rs("sortID") &"," '格式如:3,5,23,45,
  37.         rs.update
  38.         call closeRs(rs)
  39.         call closeConn()
  40.         backURL="admin_manageSort.asp"
  41. case "editSort"
  42.         if parentID="0" then
  43.                 call showMsg("根目录不能改名,请选择其他类别。")
  44.         end if
  45.         edit_sortName=replace(edit_sortName,"'","''")
  46.         if edit_sortName="" or Len(edit_sortName)>50 then
  47.                 call showMsg("请输入类别新名称(少于50字)。")
  48.         end if
  49.         '--更新名称
  50.         sql="update TBL_Sort set sortName='"&edit_sortName&"' where sortID="&parentID
  51.         conn.execute sql
  52.         call closeConn()
  53.         backURL="admin_manageSort.asp"
  54. case "deleteSort"
  55.         if parentID="0" then
  56.                 call showMsg("根目录不能删除,请选择其他类别。")
  57.         end if
  58.         '--删除所有子分类,包括自己。
  59.         sql="delete from TBL_Sort where Instr(sortPath,',"&parentID&",')>0"
  60.         conn.execute sql
  61.         '删除上述所有分类下的商品
  62.         'sql="delete from TBL_Product where Instr(sortPath,',"&parentID&",')>0"
  63.         'conn.execute sql
  64.         call closeConn()
  65.         backURL="admin_manageSort.asp"
  66. case "moveSort"
  67.         if toParentID="" or NOT IsNumeric(toParentID) then
  68.                 call showMsg("请选择目标类别。")
  69.         end if
  70.         if parentID="0" then
  71.                 call showMsg("根目录不能移动,请选择其他类别。")
  72.         end if
  73.         if toParentID=parentID then '移动到自己下,不可以
  74.                 call showMsg("目标类别与原类别相同,不能移动。")
  75.         end if
  76.         '--取原类别和目标类别的路径
  77.         dim fromPath,toPath
  78.         set rs=server.CreateObject("adodb.recordset")
  79.         sql="select sortPath from TBL_Sort where sortID="&parentID
  80.         rs.open sql,conn,0,1
  81.         if noRecord(rs) then
  82.                 call closeRs(rs)
  83.                 call showMsg("要移动的类别不存在。")
  84.         end if
  85.         fromPath=rs("sortPath") '来源节点路径
  86.         rs.close
  87.         '--取目标路径
  88.         if toParentID="0" then '移动到根目录下。
  89.                 toPath="0,"
  90.         else
  91.                 sql="select sortPath from TBL_Sort where sortID="&toParentID
  92.                 rs.open sql,conn,0,1
  93.                 if noRecord(rs) then
  94.                         call closeRs(rs)
  95.                         call showMsg("目标类别不存在。")
  96.                 end if
  97.                 toPath=rs("sortPath") '目标节点路径
  98.         end if
  99.         call closeRs(rs)
  100.         '--进行路径检查
  101.         if toPath & parentID &"," =fromPath then '如把0,2,3,5,移动到0,2,3,下,无需移动。
  102.                 call showMsg("不必移动。"+fromPath+"|"+toPath)
  103.         end if
  104.         if Instr(toPath,fromPath)>0 then '如把0,2,3,5,移动到0,2,3,5,8,下。
  105.                 call showMsg("不能移动到当前类别的子类别下。")
  106.         end if
  107.         '--更新节点路径
  108.         newPath=toPath & parentID &"," '如0,2,3,5,移动到0,1,下,那么新的前半部分path就是0,1,5,了。
  109.         sql="update TBL_Sort set sortPath='"&newPath&"'+Mid(sortPath,Len('"&fromPath&"')+1) where Instr(sortPath,'"&fromPath&"')>0"
  110.         conn.execute sql
  111.         '--更新操作节点的父节点
  112.         sql="update TBL_Sort set parentID="&toParentID&" where sortID="&parentID
  113.         conn.execute sql
  114.         '--更新对应商品路径
  115.         sql="update TBL_Product set sortPath='"&newPath&"'+Mid(sortPath,Len('"&fromPath&"')+1) where Instr(sortPath,'"&fromPath&"')>0"
  116.         conn.execute sql
  117.         call closeConn()
  118.         backURL="admin_manageSort.asp"
  119. end select %>
  120. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  121. <html>
  122. <head>
  123. <title>处理结果</title>
  124. <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
  125. <link href="css/wang.css" rel="stylesheet" type="text/css">
  126. </head>

  127. <body>
  128. <p>&nbsp;</p>
  129. <p align="center" class="font-14px"><b>操作成功,2秒后自动返回。</b></p>
  130. <script language="JavaScript" type="text/JavaScript">
  131. setTimeout("window.location='<%=backURL%>'",2000);
  132. </script>

  133. </body>
  134. </html>
复制代码
哇嘎嘎……
毛绒玩具的卖~~~

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

Archiver|手机版|安久科技提供CDN|blueidea.com ( 京ICP备05002321号 )  

GMT+8, 2012-2-9 15:29 , Processed in 0.161965 second(s), 9 queries , Gzip On, Memcache On.

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部