Asp无限下级分类设计
[收集]各式各样的无限级分类的数据库设计方案
[收集]各式各样的⽆限级分类的数据库设计⽅案第⼀种⽅案:表为两张,⼀张分类表,⼀张信息表。
表1:`ID` int(10),`cID` tinyint(3) ,`title` varchar(255),表2:`cID` tinyint(3) ,`parentID` tinyint(3),`order` tinyint(3) ,`name` varchar(255),这样可以根据cID = parentID来判断上⼀级内容,运⽤递归⾄最顶层。
第⼆种⽅案:设置parentID为varchar类型,将⽗类id都集中在这个字段⾥,⽤符号隔开,⽐如:1,3,6这样可以⽐较容易得到各上级分类的ID,⽽且在查询分类下的信息的时候,可以使⽤如:Select * From information Where cID Like "1,3%"。
不过在添加分类和转移分类的时候操作将⾮常⿇烦。
第三种⽅案:每级分类递增两位数字,这样,每级分类的数⽬限定在100个之间,分类⽅法主要为编码法;⽰例:⼀级分类:01,02,03⼆级分类:0101,0102,0103,0201,0202........三级分类:010101,010102,010103,010104..........数据库查询时使⽤ like '01%'就可得到⼀级分类01下的所有⼦分类,⾮常⽅便!如果要列出所有分类的树型结构,只需⽤⼀条语句select * from pro_class order by code,再稍微处理⼀下就可。
(其中,pro_class为产品分类表,code为类别编码)。
设计的数据库结构如下:id: 类别id,主键classname: 类名classcode: 类别编码parent: ⽗idleft_child: 最左孩⼦id(或第⼀个孩⼦)right_sibling: 右兄弟idlayer: 层级(第⼀级类别为1,第2级类别2,以此类推)以上三种的缺点?优点?还有其它⽅案吗?。
aspnet无限级分类显示
aspnet无限级分类显示2009-07-02 11:22using System;using System.Data;using System.Configuration;using System.Collections;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;public partial class Admin_SetClass : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){if (!IsPostBack){BindDrpClass();}}private void BindDrpClass(){DataTable dt = BLL.News_Class.GetList("").Tables[0];this.ClassId.Items.Clear();this.ClassId.Items.Add(new ListItem("添加根栏目", "0"));DataRow[] drs = dt.Select("bid= " + 0);foreach (DataRow dr in drs){string classid = dr["ClassID"].ToString();string classname = dr["ClassName"].ToString();//顶级分类显示形式classname = "┣" + classname;this.ClassId.Items.Add(new ListItem(classname, classid)); int sonparentid = int.Parse(classid);string blank =HttpUtility.HtmlDecode(" ") + "┗";//递归子分类方法BindNode(sonparentid, dt, blank);}this.ClassId.DataBind();}private void BindNode(int bid, DataTable dt, string blank){DataRow[] drs = dt.Select("bid="+bid);foreach (DataRow dr in drs){string classid = dr["classid"].ToString();string classname = dr["classname"].ToString();classname = blank + classname;this.ClassId.Items.Add(new ListItem(classname, classid));int getbid = int.Parse(classid);string blank2 =HttpUtility.HtmlDecode(" ") + blank + "━";BindNode(getbid, dt, blank2);}}private DataRow[] DataSet(DataSet dataSet){throw new Exception("The method or operation is not implemented.");}}数据结构classid classname bid orderid content dj编号类名父类编号排序说明等级。
ASP分级权限控制的实现
用ASP实现分级权限控制本文实现的是一个帐务管理系统中分级权限的控制,程序使用ASP和JavaScript编写,在装有IIS4.0的win NT服务器上运行,速度快,易维护。
权限级别划分如下:①、院长和财务科长:不能输入,可以无限制查询、统计;②、副院长:不能输入,可以查询、统计其分管部门的帐务;③、部门领导:不能输入,可以查询、统计本部门的帐务;④、会计:能输入各部门的帐务(一个会计有时要做几个部门的帐),只能查询、统计自己输入的帐务。
涉及的数据库和字段如下①、JK_USER数据库及字段:id(序列号),bmid(部门号),username(用户名),pwd(口令),right(权限值);②、BM数据库及字段:id(序列号) ,bmid(部门号);③、JZPZ数据库及字段:id(序列号),bm(部门),zgs(子公司),xmz(项目组),xm(项目),sr(收入),zc(支出),szfx(收支方向),szxs(收支形式),rq(日期),jbr(经办人),lrr(录入人),szsm(收支说明);④、ZGS数据库及字段:id(序列号),zgs(子公司)name(公司名),bmid(部门编号)。
1.首先进行用户身份合法性验证将用户提交的用户名和口令与数据库JK_USER中的字段对照对照,以确定其合法性,只有合法的用户(系统管理员为其开过户)才可以进入,合法用户有四种权限级别,分别赋予“1”、“2”、“3”、“4”四种权限值。
(程序略)。
2.凭证记帐(分级权限控制)凭证记帐功能是专为会计人员服务的,其他人不可以使用,如以非会计人员身份进入凭证录入界面时,只有“查询记帐凭证”功能按钮可见,其它功能按钮不可见。
录入的凭证先存放在一个临时表里,称为“未记帐凭证库”,只有运行“凭证记帐”功能后才进入“凭证库”在“未记帐凭证库”中的凭证可以修改。
部分程序如下:’非会计人员进入,不显示“凭证记帐”和“保存未记帐凭证”功能按钮if (thisPage.firstEntered) thenif session("tright")<> "1" thenbutton1.hidebutton2.hideend if…………’自动填写时间和操作人Textbox7.value=year(date) & "-" & month(date) & "-" & day(date)Textbox9.value =session("username")set cnn1=server.CreateObject("adodb.connection")set rst1=server.CreateObject("adodb.recordset")cnn1.CursorLocation=3cnn1.ConnectionTimeout =30cnn1.Open "DSN=jky"rst1.Open "select * from bm ",cnn1,1,1,adcmdtextif rst1.RecordCount >0 thenRST1.MoveFirst“Response.Write rst1.Fields("bmname") & rst1.Fields("id")rst1.MoveNextloopend ifrst1.Closerst1.Open "select zgsname from zgs where bmid=" & id,cnn1,1,1,adcmdtext if rst1.RecordCount >0 thenrst1.MoveFirstdo while not rst1.EOFListbox4.addItem cstr(rst1.Fields("zgsname"))rst1.MoveNextloopend ifrst1.Closecnn1.closecall writerstend ifend function………………’凭证记帐sub button2_onclickdim ss=Listbox1.selectedIndexResponse.Write send subsub listbox3_onchangedim id,ii=Listbox4.getCount()do while i>-1call Listbox4.removeItem(i)i=i-1loopid=listbox3.getValue (listbox3.selectedIndex)set cnn2=server.CreateObject("adodb.connection")set rst2=server.CreateObject("adodb.recordset")cnn2.CursorLocation=3cnn2.ConnectionTimeout =30cnn2.Open"DSN=jky"rst2.Open "select zgsName from zgs where bmid=" & id,cnn2,1,1,adcmdtext if rst2.RecordCount >0 thenRST2.MoveFirstdo while not rst2.EOFListbox4.addItem cstr(rst2.Fields("zgsName"))rst2.MoveNextloopend ifsub button2_onclickset cnn5=server.CreateObject("adodb.connection")cnn5.CursorLocation=3cnn5.ConnectionTimeout =30cnn5.Open"DSN=jky"cnn5.Execute "insert into jzpz(bm,zgs,xmz,xm,sr,zc,szfx,szxs,rq,jbr,lrr,szsm) select bm,zgs,xmz,xm,sr,zc,szfx,szxs,rq,jbr,lrr,szsm from wjzpz where lrr=“" & session("username") & "“"cnn5.Execute "delete from wjzpz where lrr=“" & session("username") & "“"end sub3.数据查询(分级权限控制)以凭证的字段为条件进行查询,在供选条件前有一方框供打“√”,其中“部门“条件必选(程序自动加上),部门内容由程序根据用户的权限自动从数据库中调用相应值,分公司内容根据所属部门自动调整,部分程序如下:……………’根据权限值进入相应的查询界面……………function thisPage_onenter()set cnn1=server.CreateObject("adodb.connection")set rst1=server.CreateObject("adodb.recordset")cnn1.CursorLocation=3cnn1.ConnectionTimeout =30cnn1.Open "dsn=jky"select case session("Tright")case "3"“副院长rst1.Open "select bm.bmName from jk_user ,bm where JK_user.bmid=bm.id and jk_ername =“"& session("username")& "“",cnn1,1,1,adcmdtextif rst1.RecordCount >0 thenRST1.MoveFirstdo while not rst1.EOFListbox1.addItem cstr(rst1.Fields("bmName"))rst1.MoveNextloopend ifrst1.Closerst1.Open "select zgsname from zgs ",cnn1,1,1,adcmdtextif rst1.RecordCount >0 thenrst1.MoveFirstdo while not rst1.EOFListbox2.addItem cstr(rst1.Fields("zgsname"))rst1.MoveNextloopCheckbox1.setChecked (true)case "2"“部门经理Listbox1.addItem session("bm")rst1.Open "select zgsname from zgs where bmid=" & session("bmid"),cnn1,1,1,adcmdtext if rst1.RecordCount >0 thenrst1.MoveFirstdo while not rst1.EOFListbox2.addItem cstr(rst1.Fields("zgsname"))rst1.MoveNextloopend ifrst1.Closecnn1.closeCheckbox1.setChecked (true)“Checkbox1.0case "1"“会计rst1.Open "select bmName from bm ",cnn1,1,1,adcmdtextif rst1.RecordCount >0 thenRST1.MoveFirstdo while not rst1.EOFListbox1.addItem cstr(rst1.Fields("bmName"))rst1.MoveNextloopend ifrst1.Closerst1.Open "select zgsname from zgs ",cnn1,1,1,adcmdtextif rst1.RecordCount >0 thenrst1.MoveFirstdo while not rst1.EOFListbox2.addItem cstr(rst1.Fields("zgsname"))rst1.MoveNextloopend ifrst1.Closecnn1.closecase "4"“院长rst1.Open "select bmName from bm ",cnn1,1,1,adcmdtextif rst1.RecordCount >0 thenRST1.MoveFirstdo while not rst1.EOFListbox1.addItem cstr(rst1.Fields("bmName"))rst1.MoveNextloopend ifrst1.Closerst1.Open "select zgsname from zgs ",cnn1,1,1,adcmdtextListbox2.addItem cstr(rst1.Fields("zgsname"))rst1.MoveNextloopend ifrst1.Closecnn1.closeend selectend if…………end function’按照权限查询凭证sub button1_onclickdim rst2,cnn2,str,idim bm(1),zgs(1),xmz(1),xm(1),szfx(1),szxs(1),rq(2),jbr(1)bm(0)=Checkbox1.getChecked()if bm(0) thenbm(1)=Listbox1.getText(Listbox1.selectedIndex )str=" and bm=“" & bm(1) & "“"end ifzgs(0)=Checkbox2.getChecked()if zgs(0) thenzgs(1)=Listbox2.getText(Listbox2.selectedIndex )str=str & " and zgs =“"& zgs(1) & "“"end ifxmz(0)=Checkbox3.getChecked()if xmz(0) thenxmz(1)=trim(txtxmz.value )str=str & " and xmz like “%" & xmz(1) & "%“" end ifxm(0)=Checkbox4.getChecked()if xm(0) thenxm(1)=trim(tztxm.value )str=str & " and xm like “%" & xm(1) & "%“" end ifszfx(0)=Checkbox5.getChecked()if szfx(0) thenszfx(1)=Listbox3.getText(Listbox3.selectedIndex )str =str & " and szfx =“" & szfx(1) & "“"end ifszxs(0)=Checkbox6.getChecked()if szxs(0) thenszxs(1)=Listbox4.getText(Listbox4.selectedIndex )str =str & " and szxs =“" & szxs(1) & "“"end ifjbr(0)=Checkbox8.getChecked()if jbr(0) thenset cnn2=server.CreateObject("adodb.connection")set rst2=server.CreateObject("adodb.recordset")cnn2.CursorLocation=3cnn2.ConnectionTimeout =30cnn2.Open "dsn=jky"Response.Write "<table border=“1“ cellPadding=0 cellSpacing=0 width=“650“ height=“33“ >" Response.Write "<tr>"Response.Write "<td width=“100%“ colspan=“6“ height=“44“ align=“middle“ bg color=lightblue>" Response.Write "<p align=“center“><b><font color=“#000084“>记帐凭证列表" Response.Write "</font></b></p></td></tr> "Response.Write "<tr>"Response.Write "<td width=“15%“ bgcolor=lightsteelblue>"Response.Write "部门</td>"R esponse.Write "<td width=“20%“bgcolor=lightsteelblue>"Response.Write "子公司</td>"Response.Write "<td width=“15%“ bgcolor=lightsteelblue>"Response.Write "项目组</td>"Response.Write "<td width=“15%“ bgcolor=lightsteelblue>"Response.Write "项目名/合同号</td>"Response.Write "<td width=“15%“ bgcolor=lightsteelblue>"Response.Write "收入金额(万元)</td>"Response.Write "<td width=“15%“ bgcolor=lightsteelblue>"Response.Write "支出金额(万元)</td></tr>"if session("Tright")="1" then“Response.Write "AAAAAAAA"r st2.Open "select * from jzpz where id>0 and lrr=“" & session("username") & "“" & str ,cnn2,1,1,adcmdtextelse“Response.Write "FFFFFFFFFFFFF"rst2.Open "select * from jzpz where id>0 " & str ,cnn2,1,1,adcmdtextend ifif rst2.RecordCount >0 thenrst2.MoveFirstrst2.PageSize =20rst2.AbsolutePage =1i=0do while not rst2.EOF and i< rst2.PageSizeResponse.Write "<tr>"Response.Write "<td width=“15%“ bgcolor=lightgrey>"& rst2.Fields("bm")& "</td>"Response.Write "<td width=“15%“ bgcolor=lightgrey>"& rst2.Fields("zgs")& "</td>"Response.Write "<td width=“15%“ bgcolor=lightgrey>"& rst2.Fields("xmz")& "</td>"Response.Write "<td width=“15%“ bgcolor=lightgrey><a href=“FMjz1.asp?Id="& rst2.Fields("id") & "“target=“_blank“>" & rst2.Fields("xm")& "</a></td>"Response.Write "<td width=“5%“ bgcolor=lightgrey>"& rst2.Fields("sr")& "</td>"Response.Write "<td width=“5%“ bgcolor=lightgrey>"& rst2.Fields("zc")& "</td>"loopend ifResponse.Write "</table>"Response.Write "</div>"j= rst2.PageCountResponse.Write "<P align=center><b>共有页数:"for i=1 to jResponse.Write "<a href=“Fmjzpzck1.asp?ID=" & i & "“ target=“_blank“>" & i & "</a>" & " "if j mod 10= 0 thenResponse.Write "<br>"end ifnextResponse.Write "</b></p>"rst2.Closecnn2.Close…………end sub应用以上程序,可以根据用户的权限,按照用户的要求实行订制查询,该系统在win NT、IIS4.0和win98、PWS上运行通过。
php实现无限级分类实现代码(递归方法)
php实现⽆限级分类实现代码(递归⽅法)开始以为这样的功能似乎很难,之前也做过⼀个百科的东西,其中也涉及到了分类的功能,不过不是⽆限级的分类,⽽是简单的实现了固定的三级分类,当时是⾃⼰设计的,想在想起来实现⽅法太⼟了,其实三级分类也只是⽆限级分类的⼀种特殊情况⽽已嘛。
经过⼀段时间考虑,已经有了⼀些眉⽬,到⽹上⼀查,原来这样的东西铺天盖地,呵呵。
其实⽆限级下拉列表功能是很简单的,⽆⾮就是⽤⼀个递归算法就好啦。
⾸先要设计数据库,需要建⼀个表,⾥⾯存储分类信息,⾄少需要3个字段,第⼀个是主键(ID),第⼆个是⽗级分类ID(parentid),第三个是分类的名称(classname)。
可能的⼀种效果是:ID PARENTID CLASSNAME1 0 ⼀级分类A2 0 ⼀级分类B3 1 ⼆级分类A4 1 ⼆级分类B主要思路:⾸先看第三⾏和第四⾏,⽗类ID(PARENTID)的值是1,表⽰属于id=1这个类的⼦类,⽽,⼀,⼆两⾏因为是⼀级分类,没有上级分类,所以⽗类ID(PARENTID)的值是0,表⽰初级分类,依次类推便实现了⽆限级分类。
最终的效果是:├⼀级分类A├─┴⼆级分类A├─┴⼆级分类B├⼀级分类B然后就是程序,这⾥以PHP作为描述语⾔,可以很⽅便的改成其他语⾔,因为原理相似,就是⼀个递归⽽已。
复制代码代码如下:<?php$dbhost = "localhost"; // 数据库主机名$dbuser = "root"; // 数据库⽤户名$dbpd = "123456"; // 数据库密码$dbname = "test"; // 数据库名mysql_connect($dbhost,$dbuser,$dbpd); //连接主机mysql_select_db($dbname); //选择数据库mysql_query("SET NAMES 'utf8'");display_tree("├",0);function display_tree($tag,$classid) {$result = mysql_query("SELECT *FROM ylmf_classWHERE parentid = '" . $classid . "';");while ($row = mysql_fetch_array($result)) {// 缩进显⽰节点名称echo $tag.$row['classname'] . "<br/>";//再次调⽤这个函数显⽰⼦节点的⼦节点display_tree($tag."─┴",$row['id']);}}>这样递归⽅法,对于⼤量的⼦栏⽬是个负担,⼀些成熟的cms系统。
asp实现无限级分类的问题
asp实现无限级分类的问题分类算法要解决的问题在网站建设中,分类算法的应用非常的普遍。
在设计一个电子商店时,要涉及到商品分类;在设计发布系统时,要涉及到栏目或者频道分类;在设计软件下载这样的程序时,要涉及到软件的分类;如此等等。
可以说,分类是一个很普遍的问题。
1、分类算法常常表现为树的表示和遍历问题。
那么,请问:如果用数据库中的一个Table 来表达树型分类,应该有几个字段?2、如何快速地从这个Table恢复出一棵树;3、如何判断某个分类是否是另一个分类的子类;4、如何查找某个分类的所有产品;5、如何生成分类所在的路径。
6、如何新增分类;在不限制分类的级数和每级分类的个数时,这些问题并不是可以轻松回答的。
本文试图解决这些问题。
分类的数据结构我们知道:分类的数据结构实际上是一棵树。
在《数据结构》课程中,大家可能学过Tree 的算法。
由于在网站建设中我们大量使用数据库,所以我们将从Tree在数据库中的存储谈起。
为简化问题,我们假设每个节点只需要保留Name这一个信息。
我们需要为每个节点编号。
编号的方法有很多种。
在数据库中常用的就是自动编号。
这在Access、SQL Server、Oracle 中都是这样。
假设编号字段为ID。
为了表示某个节点ID1是另外一个节点ID2的父节点,我们需要在数据库中再保留一个字段,说明这个分类是属于哪个节点的儿子。
把这个字段取名为FatherID。
如这里的ID2,其FatherID就是ID1。
这样,我们就得到了分类Catalog的数据表定义:Create Table [Catalog]([ID] [int] NOT NULL,[Name] [nvarchar](50) NOT NULL,[FatherID] [int] NOT NULL);约定:我们约定用-1作为最上面一层分类的父亲编码。
编号为-1的分类。
这是一个虚拟的分类。
它在数据库中没有记录。
如何恢复出一棵树上面的Catalog定义的最大优势,就在于用它可以轻松地恢复出一棵树—分类树。
ASP实现三级分类AC版
IfCheckRs("BigClass")=0AndCheckRs("SmallClass")=0Then
sql="insertintoArticleClass(ClassName,BigClass,OrderID)values('"&ClassName"',"&ClassID","&OrderID")"
BigRs.openBigSql,conn,3,2
WhileNotBigRs.eof
response.write"<optionvalue='"&BigRs("ClassID")"'>├"&BigRs("ClassName")"</option>"
response.End
Endif
IfOrderID=""OrNotIsNumeric(OrderID)Then
OrderID=0
Endif
IfClassID=""OrNotIsNumeric(ClassID)Then
sql="insertintoArticleClass(ClassName,OrderID)values('"&ClassName"',"&OrderID")"
[ASP]无限级分类的简单算法实现及代码重点讲解
一、前言很多情况下二级分类已经不能满足需要了,而网上可用的多级分类的例子实在是不好找,故有此文。
/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,"。
asp无限级显示分类代码
asp无限级显示分类代码为了方便使用分类,我定义了一个分类表category,里面字段是id(自动编号) cat_name(分类名) parent_id(父ID,对应本表ID) cat_order(顺序) is_show(是否显示) u_id(这个用来区别是新闻分类,还是产品分类,还是其他分类),为了方便,我将这些分类全部放在这张表中。
在给客户添加分类的时候,结果有太多的分类,本来前台显示的时候,将它们全部显示出来了,好长。
客户提出修改意见,要求将它们改成点击大分类,才可以将其子分类显示出来,并且每个分类下面还有一条虚线,并且大分类前面有个图片加号,展开后要变成减号。
<script>function fd(id,num){t=$("c"+id+"_1").style.display;if(t=="none"){t1="block";t2="images/fll_34.gif";}else{t1="none";t2="images/fll_34.gif";}for(i=1;i<=num;i++){$("c"+id+"_"+i).style.display=t1;$("d_"+id).src=t2;}}function $(id){return document.getElementById(id);}</script>这是asp无限级显示分类代码,并给这些分类加上id<%'功能:asp无限级显示分类+js显示与隐藏'参数:parent_id为父ID,stype为新闻,产品,文章大分类'原创文章,转载请保留些信息,谢谢function cat111(parent_id,stype)set rs1 =server.createobject("adodb.recordset")sql="select cat_name,cat_id,parent_id from category where parent_id="&parent_id&" and u_id="&stype&" and is_show=1 order by cat_order asc"set rs1=conn.execute(sql)If rs1.eof ThenElseif(depath>2) thendisplay2="none"elsedisplay2="block"end ifdim jj=1do while not rs1.eofcat_name1 = rs1("cat_name")cat_id1 = rs1("cat_id")parent_id1=rs1("parent_id")'******************下面是你要显示的******************'m9=0sql2="select count(cat_id) as t from category where parent_id="&cat_id1&" and u_id="&stype&""set rs2=server.createobject("adodb.recordset")set rs2=conn.execute(sql2)if not rs2.eof thenm9=rs2("t")elsem9=0end ifrs2.closeif(depath<=2) thenmgif="images/-.gif"a="block"elseif(m9>0) thenmgif="images/+.gif"elsemgif="images/-.gif"end ifif(depath=4) thena="block"elsea="none"end ifend ifcatstr=catstr & "<tr id=""c"&parent_id&"_"&j&""" style=""display:"&a&"""><td width=""25"" align=""center"" valign=""middle"" class=""dotted_class""><img src="""&mgif&""" width=""12"" height=""11"" id=""d_"&cat_id1&"""></td><td class=""dotted_class leftcatcss"">"if(m9>0) thencatstr=catstr&"<a href=""javascript:void(0);"" _fcksavedurl="""javascript:void(0);"""_fcksavedurl="""javascript:void(0);"""onclick=""fd("&cat_id1&","&m9&")"">" &vbnewline elsecatstr=catstr&"<a href=""products.asp?id="&cat_id1&""" target=""_blank"">"&vbnewlineend iffor i=1 to depathcatstr=catstr&" "Nextcatstr=catstr&cat_name1&"</a></td></tr>"&vbnewlinem9=0sql2="select cat_name,cat_id from category where parent_id="&parent_id1&" and u_id="&stype&" order by cat_order asc"set rs2=server.createobject("adodb.recordset")set rs2=conn.execute(sql2)if not rs2.eof thendepath=depath+4call cat111(cat_id1,stype)end ifrs2.closeset rs2=nothingdepath=depath-4'******************上面是你要显示的******************'j=j+1rs1.movenextloopEnd Ifrs1.closeset rs1=nothingend Function%>在使用这个函数之前加上catstr=""然后再call,下面的虚线加在css中的dotted_class里面,这样就搞定了。
数据库“路径法”无限级分类节点算法设计与实现
分 类 的设 计原理 , 实现 算 法 , 并编 写存 储 过程 、 函数 等 , 接在服 务 器 端 实现 此操 作过 程 。数 据 库服 务 直 器 端代 码具 有 执行效 率 高、 度 快 、 费资源 小等优 速 耗
归的查询 , 就可 以把各个级别查 询 出来 ; 优点是结 构简 单清晰 , 可以无限扩 充级 别 , 易添加 级别数 据 ; 点 容 缺 是用“ 递归算法” 创造 的结构 , 对分类数 据查询难 度高 、 效率低 , 要精确查询某个分类及层 次比较 困难 。
限 级 ” 。
信 息社 会 中 , 数据 信 息 大量 以数 据 库 为媒 介进
行 存 储 , 提 高 数 据 的检 索 速 度 , 了提 高 计 算 机 要 除 软、 硬件性 能 , 合理 设 置 使 用索 引 等 , 可 以通 过进 亦
行数 据信 息 的类 别划 分来 提高 检索性 能 。应 用系统
S re 服 务器 端 代 码 为例 , 析在 数 据 库 中无 限级 ev r 分
1 2 递 归法无 限级分 类 . 数据 库无 限级分类 常用 “ 递归 法 ” 即仅 建立 一 ,
张分类 表 , 采用 “ 自连接 ” 作 , 操 主键 、 键 都 在 此 表 外 上; 理论上 , 表的数据行无限 , 级别无限 , 则 采用循 环递
数据 库设 计 时 , 分类 设 置可 以分 为 :固定级 分类 ” “ 和
“ 限级 分类 ” “ 限级 分类 ” 无 。 无 常采 用 “ 归法” 递 进行
2 “ 径 法 ” 类设 计 原 理 路 分
2 1 表 结 构 及 示 例 数 据 图 .
设计 , 因 “ 归法 ” 行 “ 归 ” 作 难 度 高 , 率 但 递 进 递 操 效
ASP XML JavaScript 实现动态无限级联动菜单
// Email :fason_pfx@
// HomePage :
// Blog :/fason/
// /fason/
//-----------------------------------------------------/
function attachSelect(sXMLSrc, aSel, sStore) {
var oXML = CreateXmlDocument();
var oDocument = null;
<select>
s=s & ",'Select" & i & "'" '把每个<select>的id 保存在变量s,它的格式为:id1,id2,id3,id4
next
xmlDoc.save filename '正式保存Xml文件
CloseXml xmlDoc '关闭Xml文件
//-----------------------------xmlselect.js文件开始-------------------------------
//-----------------------------------------------------/
// NichName :fason
ClassName nvarchar 50 类别名称
ParentID int 2 连接到组(0表示是父类)
'####################################我的ASP代码如下####################################
ASP+ACCESS实现的无限级目录树
set rs=nothing
end function
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>=========无限级目录树=========</title>
关键代码:
<%
set conn=server.createobject("ADODB.CONNECTION")
connstr="DBQ="+server.mappath("db1.mdb")+";DefaultDir=;DRIVER={Microsoft Access Driver (*.mdb)};"
<style type="text/css">
<!--
.menu1 {
background-image: url(folder1.gif);
background-repeat: no-repeat;
height: 17px;
left: 32px;
padding-left: 32px;
right: 1px;
bottom: 1px;
}
a:active {
font-size: 9pt;
color: #000000;
text-decoration: none;
}
用ASP和SQL Server实现网站分级管理
2 需 要 解 决 的 几 个 问 题
A P在 服 务 器 上 运 行 的 过 程 是 浏 览 器 从 We S b服 务 器 上 请 求 * .s ap文 件 时 , S A P脚 本 开 始 运 行 ; 然 后 , b服 务 器 调 用 A P A P全 面 读 取 请 求 的 文 件 , 行 所 有 脚 本 命 令 , 将 We We S ,S 执 并 b页 传 送 给 浏 览 器 . 由
关键词 : 网站 ; 网站 分级 管 理 ;S ; LSr r A PS e v Q e
中 图 分 类 号 :P9 . T 330 文 献 标 识 码 : 文 章 编 号 :0015(020—17 3 7 A 1 — 420 )3 9— 0 6 0 0
传 统 的 网 站 是 以 H ML构建 的 静 态 网 站 及 C I 的 动 态 网 站 . T T G 下 H ML构 建 的 网站 只 能 让 用 户 通 过 F R 形 式 提 交 表 单 信 息 , 在 C I 构 建 的 网 站若 要 实 现 良好 的交 互 , 需 要 用 比 较 高 级 的语 言 编 写 O M 而 G 下 则
J n., 00 u 2 2
用 A P和 S L S re 实 现 网 站 分 级 管 理 S Q ev r
陆 永 祯 , 云 龙 孙
( 山 钢 铁 学 院 学 生 处 , 宁 鞍 山 I 4 0 ) 鞍 辽 10 2
摘 要 : 对 目前 网站更新 困难 、 针 管理 费 用 高的 现 象 , 出 了 网站 分级 管理 的 概 念 . 述 了运 用 A P与 S L 提 论 S Q
1 AS 和 S L S re 数 据 库 P Q evr
动 态 服 务 器 网 页 A P A t eS re ae) 服 务 器 端 脚 本 编 写 环 境 , 文 本 文 件 , H ML标 志 符 S ( c v e rP gs 是 i v 是 由 T
php 递归实现无限分类原理
php 递归实现无限分类原理(原创版)目录1.引言2.PHP 递归实现无限分类的原理3.实际应用案例4.结论正文1.引言在互联网时代,信息量日益增多,人们对于信息的管理和分类需求也日益增强。
为了能够更好地管理和分类信息,人们常常会使用无限级分类这一技巧。
例如,在部门组织、文章分类、学科分类等方面,无限级分类被广泛应用。
而 PHP 作为一种流行的编程语言,可以很好地实现无限级分类的功能。
本文将介绍 PHP 递归实现无限分类的原理及其实际应用案例。
2.PHP 递归实现无限分类的原理(1)递归函数的定义要实现无限级分类,首先需要创建一个递归函数。
递归函数是一种在函数体内部调用自身的函数。
在 PHP 中,可以定义一个递归函数来实现无限级分类。
(2)无限分类的实现在实际应用中,无限级分类通常需要一个父类和多个子类。
以部门组织为例,可以有一个总的部门类别,下面分别有各个具体的部门。
在 PHP 中,可以通过递归函数来实现这个功能。
假设有一个部门类(Department),它包含一个属性($parent)表示父部门,以及一个属性($children)表示子部门。
可以通过递归函数来实现部门分类:```phpfunction getDepartments($parent_id = 0) {$departments = array();$sql = "SELECT * FROM department WHERE parent_id = $parent_id";$result = db_query($sql);while ($row = db_fetch_array($result)) {$department = new Department($row["id"],$row["name"], $row["parent_id"]);$departments[] = $department;$department->getChildren($parent_id);}return $departments;}```上述代码中,`getDepartments`函数接收一个参数`$parent_id`,表示要查询的父部门 ID。
php实现无限级分类(递归方法)
php实现⽆限级分类(递归⽅法)相信很多学php的很多⼩伙伴都会尝试做⼀个⽹上商城作为提升⾃⼰技术的⼀种途径。
各种对商品分类,商品名之类的操作应该是得⼼应⼿,那么就可以尝试下⽆限级分类列表的制作了。
到⽹上⼀搜php⽆限极分类,很多,但好多都是⼀个,并且,写的很乱,代码很多,让我们怎么学习嘛,那些都不靠谱,还是⾃⼰捣⿎捣⿎⽆限极分类了。
什么是⽆限级分类? ⽆限级分类是⼀种分类技巧,例如部门组织,⽂章分类,学科分类等常⽤到⽆限级分类,将其简单理解成分类就好了。
其实我们仔细想⼀下,⽣活中的分类简直太多了,⾐服可以分为男装和⼥装,也可以分为上⾐和裤⼦,也可以根据年龄段分类。
分类⽆处不在,分类显得“⽆限”。
我这⾥就不说⽆限分类的必要性了。
⽆限级分类原理简介 ⽆限分类看似"⾼⼤上",实际上原理是⾮常简单的。
⽆限分类不仅仅需要代码的巧妙性,也要依托数据库设计的合理性。
要满⾜⽆限级分类,数据库需要有两个必须的字段,id,pid。
id⽤来标识⾃⾝,⽽pid则是⽤来表明⽗级id。
也就是说,每个分类记录不仅描述了⾃⾝,还描述了与其关⼼最为紧密的另⼀个id。
看似复杂的事情被这样⼀个⼩技巧解决了。
闲话不多说,该展现本⽂的实例了。
作为⼀个狂热海贼迷,这篇的实例我就以《海贼王》⼈物组织做案例。
数据库准备: 建表onepiece:create table onepiece(id int auto_increment,pid int not null,name varchar(225) not null,primary key(id)); 插⼊测试数据:insert onepiece values(1,0,'海军'),(2,0,'海贼'),(3,0,'⾰命军'),(4,1,'青雉'),(5,1,'⾚⽝'),(6,1,'黄猿'),(7,2,'四皇'),(8,2,'七武海'),(9,2,'草帽海贼团'),(10,9,'索隆'),(11,7,'⾹克斯'),(12,8,'多弗朗明哥'),(13,8,'克洛克达尔'); 这⾥还是科普下海贼王⾥⾯的设定:世界分为三⼤阵营:海军,海贼,⾰命军。
php无限分类
php⽆限分类⽆限分类,是指从⼀个最⾼分类开始,每个⼦分类都可以分出⾃⼰的若⼲个⼦分类,可以⼀直分下去,称为⽆限级分类;⽐如⼀棵树,从⼀根树⼲开始,分出多个树枝,⽽这些树枝⼜分出其他的分⽀,理论上是可以⽆限分裂下去的;再⽐如,⼀个家庭可以有若⼲个⼦⼥,我们把这些⼦⼥看做是第⼀级分类。
⽽这些⼦⼥,⼜会各⾃组建⾃⼰的家庭,当他们有了⾃⼰的后代,就是第⼆级分类,如果每个家庭都有⼀个以上的⼦⼥,理论上是可以⽆限分裂的;在php中,⽆限分类的表现形式如下图所⽰;我们同过id和pid两个字段来连接⽗级分类和⼦集分类,这样就可以找到某⼀级分类的祖先和它的后代,例如顶级分类>华语歌⼿>流⾏歌⼿>流⾏男歌⼿>周杰伦;通过pid和id来看的话,就是:0-1 , 1-2 , 2-4 , 4-5 , 5-6 (pid在前,id在后);光是做出数据还不够,我们还需要把数据展⽰出来,这个时候,我们就需要⽤到⽆限分类的递归算法了。
这⾥先解释⼀下什么是递归,递归是函数调⽤⾃⾝的⼀种编程技巧,通过调⽤⾃⾝达到循环的⽬的。
那么问题来了,我们为什么不直接使⽤循环呢?如果直接使⽤循环的话,我们就没办法很好的解决参数的问题,特别是当处理⼀些复杂问题的时候,什么情况下初始化参数,什么情况下累加参数,都会需要额外的思考。
不如递归的思路清晰。
看⼀个简单的递归例⼦;1function test(&$b=0){2$b++;3if($b<10){4 test($b);5 }67return$b;8}9echo test();递归作为循环的⼀种变式,那么它也需要跳出循环的条件,或者是继续循环的条件。
这⾥的&$b是参数传递的⼀种⽅式,指引⽤参数本⾝,通过&传递的参数,才会不断累积;回到刚刚的分类:$host='127.0.0.1';$db_user='root';$db_pass='root';$db_name='chenbk';$timezone="Asia/Shanghai";$link=mysqli_connect($host,$db_user,$db_pass,$db_name);mysqli_query($link,"SET names UTF8");header("Content-Type: text/html; charset=utf-8");function tree($link,&$treeList=array(),$pid = 1,$count = 0) { //$link为数据库连接,&$treeList为输出数组,因为需要累积结果,所以加上引⽤$count+=2; //count为识别分级深度的标识$result = mysqli_query($link,"SELECT * FROM chen_category WHERE parentId={$pid}");while ($row=mysqli_fetch_assoc($result)) {$row['count'] = $count;$row['name'] = str_repeat(' ', $count).'|-'.$row['name']; //通过分级深度的标识,来给分类缩进效果$treeList[] = $row; //把查询到的结果存储起来 tree($link,$treeList,$row['id'],$count); //再次调⽤⾃⾝,这时的pid为上⼀条数据的id从⽽找到上⼀条数据的⼦分类;}return$treeList; //输出结果}$values=tree($link);echo '<select name="parentId" id="">';foreach ($values as$key => $value) {echo '<option value="'.$value['id'].'">'.$value['name'].'</option>';}echo '</select>';这个函数的运⾏流程为:1.通过pid=0找到最⾼分类2.给它加上层级深度,通过层级深度加上缩进效果,然后把这条数据存起来。
php无限级分类数据库设计和sql实现
昨天看到qq群里面有人在问无限级分类的问题,我想了下,我怎么没有把以前写过的这个无限级分类的实现方法总结一下呢,想想真是遗憾,所以今天就总结一下php的无限级分类的数据库试剂和sql实现。
很多程序员再遇到问题的时候总是想能上网一下搜一个一模一样的实现方法出来,但是我们想一想,首先是这样不现实,第二是这样对我们本身的发展没有什么好处,好的程序员当困惑在某一点的时候,都是只查这某一点的实现原理,当突破了这一点,就应该好好的总结,然后写出自己风格的代码。
我们会了这些一个个小的部件,通过自己的组合和规划就能实现很多很多的功能,这样当你再遇到类似的问题时就不会再完全靠搜搜解决方法来实现了。
这样你就有了自己的一套体系。
好了,说一下这个无限级分类,其实这个分类比较简单,只是很多php程序对于myqsl 的一些函数不是很了解。
这里我们用到了mysql的一个concat函数,他可以将多个字段进行组合,并且,以他组合后的结果排序是按照类似拼音排序,或奥运奖牌榜排序一样,先比较第一位,第一位大就大,第一位相同再比较第二位,这样以此类推。
有了这样的原理,那么我们组合分类的时候可以加一个path字段,这个字段存储其所有上级类别的“路径”这个是数据库设计和一些地区信息为例北京和山东为顶级栏目,海淀和泰安是二级栏目,宁阳是三级栏目,宁阳隶属于泰安。
现在他们的顺序是杂乱无章的,我们要实现的结果就是北京、海淀、山东、泰安、宁阳。
这样的顺序,所以,我们可以用这个sql语句select id,concat(path,’-',id) as abspath,name from admin order by abspath结果就是。
这正是我们想要的结果,而要在页面中如何显示就我们自己定义了,我们可以根据这个abspath这个新定义字段来分割一下,就可以实现等级的缩进效果。
好了。
这个是核心,有了这个比如你如何添加类别记录等,我们认为大家应该可以琢磨出来吧,看一下数据结构就明白,但选择顶级栏目时可以让他的pid和path都为0,而选择了一个父级栏目就将其父id作为自己的pid,其父的path连上其父的id作为自己的path。
【php】php不用递归完成无限分类,从表设计入手完整演示过程
【php】php不⽤递归完成⽆限分类,从表设计⼊⼿完整演⽰过程⽆限分类是什么就不废话了,可以⽤递归实现,但是递归从数据库取东西⽤递归效率偏低,如果从表设计⼊⼿,就很容易做到⽹站导航的实现,下⾯是某论坛导航,如下图⽹上⽆限分类⼤多不全⾯,今天我会从设计表开始,⾸先我们先做视图界⾯,<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>⽩超华-博客园</title></head><body><form action="" method="post">分类名称 <input type="text" name="cat_name" value=""><br><br>上级分类 <select name="cat_root"><option value="">顶级分类</option></select><input type="submit"></form></body></html>⽹页展⽰如下:我们⾸先来设计表,(需要实验的朋友直接复制SQL语句到cmd执⾏即可)#创建数据库CREATE DATABASE tree;#选择数据库USE tree;#创建表CREATE TABLE tree(cat_id smallint UNSIGNED AUTO_INCREMENT comment '类别ID',cat_name varchar(10) NOT NULL comment '类别名称',parent_id smallint NOT NULL DEFAULT 0 comment '类别⽗ID',path varchar(20) NOT NULL comment '路劲结构',PRIMARY KEY(cat_id))engine=MyISAM charset=utf8;表结构如下:其中字段 path 就是不⽤递归操作的重点,path⽤来表⽰下级分类深⼊的情况,啊哈⽤语⾔还不是很好描述,举个简单例⼦吧,理解的朋友就直接跳过了!path是通过字符串存储的形式来表⽰类别之间的层关系,通过字符串函数我们可以知道path中 ' - ' 的数量,如果有⼀个表⽰它上⾯有⼀个⽗分类,如果有两个表⽰它上⾯有两个⽗分类.以此类推实现⽆限分类。
php无限查询下级,php递归统计下级总数,php获取无限子级
php⽆限查询下级,php递归统计下级总数,php获取⽆限⼦级因项⽬需要需要统计⽤户⽆限下级计算分销佣⾦,计算每⽉分红,计算⽆限下级团队的业绩,需要先获得某个会员的⽆限下级成员。
先看看数据库中的member表字段//1.整个会员表的数据$member = array(array('id'=>1, 'pid'=>0, 'nickname' => 'A'),array('id'=>2, 'pid'=>1, 'nickname' => 'B'),array('id'=>3, 'pid'=>1, 'nickname' => 'C'),array('id'=>4, 'pid'=>8, 'nickname' => 'D'),array('id'=>5, 'pid'=>3, 'nickname' => 'E'),array('id'=>6, 'pid'=>3, 'nickname' => 'F'),array('id'=>7, 'pid'=>3, 'nickname' => 'G'),array('id'=>8, 'pid'=>8, 'nickname' => 'H'));/**2.获取某个会员的⽆限下级⽅法⾮递归⽅法*$members是所有会员数据表,$mid是⽤户的id*/function GetTeamMember($members, $mid) {$Teams=array();//最终结果$mids=array($mid);//第⼀次执⾏时候的⽤户iddo {$othermids=array();$state=false;foreach ($mids as $valueone) {foreach ($members as $key => $valuetwo) {if($valuetwo['pid']==$valueone){$Teams[]=$valuetwo[id];//找到我的下级⽴即添加到最终结果中$othermids[]=$valuetwo['id'];//将我的下级id保存起来⽤来下轮循环他的下级array_splice($members,$key,1);//从所有会员中删除他$state=true;}}}$mids=$othermids;//foreach中找到的我的下级集合,⽤来下次循环} while ($state==true);return $Teams;}$res=GetTeamMember($member ,1);var_dump($res);递归⽅法//获取⽤户的所有下级IDfunction get_downline($members,$mid,$level=0){$arr=array();foreach ($data as $key => $v) {if($v['pid']==$mid){ //pid为0的是顶级分类$v['level'] = $level+1;$arr[]=$v;$arr = array_merge($arr,get_downline($data,$v['id'],$level+1));}}return $arr;}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、前言很多情况下二级分类已经不能满足需要了,而网上可用的多级分类的例子实在是不好找,故有此文。
/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语句就搞定啦。
复制内容到剪贴板(Access)sql="delete from T_Sort where Instr(sortPath,',"&parentID&",')>0"复制内容到剪贴板(MS SQL)sql="delete from T_Sort where CHARINDEX(',"&parentID&",',sortPath)>0"本算法的精华就在这里啦,仔细想想吧,sortPath最后那个逗号的作用也在这里啦。
<4>删除上述所有节点下的商品。
同上,表名不同而已。
复制内容到剪贴板(Access)sql="delete from T_Product where Instr(sortPath,',"&parentID&",')>0"复制内容到剪贴板(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,"就行了。
复制内容到剪贴板(Access)sql="update T_Sort set sortPath='"&newPath&"'+Mid(sortPath,Len('"&fromPath&"')+1) where Instr(sortPath,'"&fromPath&"')>0"复制内容到剪贴板(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>取直接子类别,很简单啦。
复制内容到剪贴板sql="select sortID,sortName from T_Sort where parentID="&sortID就行啦。
<2>一般我们都会显示一个当前位置,就是分类所在的路径,怎么办呢?难道去递归查询吗?当然不,我这里用了一个小技巧。
浏览某一个分类的时候,我们会有一个sortID,可以根据它从T_Sort取得sortPath....不说了,大家看示范代码吧,不懂问我。
范例代码见图8。
[center]图八[/center]显示的时候用复制内容到剪贴板<%for i=1 to UBound(myArray)response.write "-> <a href='product.asp?sortID="&myArray(i)&"'>"&getValueByID(myArray(i),nameA rray)&"</a>"next%>就OK了。
getValueByID是我写的一个Function,见后。
<3>显示该类别及其所有子类别下的所有商品。
复制内容到剪贴板sql="select * from T_Product where Instr(sortPath,',"&sortID&",')>0"如果只显示该类别下的商品,那么就用parentID判断就行了。