表:tree
表结构:
测试数据:
算法:使用递归实现
======================================
asp代码:
<
%@ Language
=
VBScript%
>
< % Option Explicit % >
< %
Dim oConn, sSql
Call DBConnBegin()
Dim sTableName
Dim nCurrent, nLen, aTree()
sTableName = " tree "
nCurrent = 1
nLen = GetRescordCount()
ReDim aTree(nLen)
Call GetPowerName( 0 )
' Dim i
' For i = 1 To nLen
' Response.Write aTree(i) & "<br>"
' Next
Call DBConnEnd()
Function GetRescordCount()
GetRescordCount = oConn.Execute( " select count(id) from " & sTableName)( 0 )
End Function
Sub GetPowerName(s_Id)
Dim n_ParentId, j, oRs
Set oRs = Server.CreateObject( " ADODB.Recordset " )
sSql = " select id,PowerName,Layer from " & sTableName & " where ParentId= " & s_Id
oRs.Open sSql, oConn, 0 , 1
Do While Not oRs.Eof
For j = 1 To oRs( " Layer " )
response.write " "
Next
aTree(nCurrent) = oRs( " PowerName " )
response.write aTree(nCurrent) & " <br> "
nCurrent = nCurrent + 1
n_ParentId = oRs( " id " )
Call GetPowerName(n_ParentId)
oRs.MoveNext
Loop
oRs.Close
Set oRs = Nothing
End Sub
Sub DBConnBegin()
' 如果数据库对象已打开,不要再打开
If IsObject (oConn) = True Then Exit Sub
' 你可以不需要打开数据库连接对象而直接打开记录集对象,但如果你需要打开多个记录集对象的话,效率是很低的。
' 如果你不创建一个数据库连接对象,ADO会在每个记录集打开时自动创建一个新的数据库连接对象,就算你用的是相同的SQL语句。
Set oConn = Server.CreateObject( " ADODB.Connection " )
On Error Resume Next
' Provider=SQLOLEDB.1;Server=(local);Initial Catalog =cx_soft;Integrated Security=SSPI;
' Provider=SQLOLEDB.1;Server=(local);Initial Catalog =cx_soft;Trusted_Connection=yes;
oConn.Open " Provider=sqloledb.1;Data Source=(local);Initial Catalog=AspNetTest;User Id=sa;Password=; "
If Err.Number > 0 Then
' 完全地退出正在运行的脚本
Response.End
End If
' 创建一个记录集
End Sub
Sub DBConnEnd()
On Error Resume Next
oRs.Close
Set oRs = Nothing
oConn.Close
Set oConn = Nothing
End Sub
% >
< % Option Explicit % >
< %
Dim oConn, sSql
Call DBConnBegin()
Dim sTableName
Dim nCurrent, nLen, aTree()
sTableName = " tree "
nCurrent = 1
nLen = GetRescordCount()
ReDim aTree(nLen)
Call GetPowerName( 0 )
' Dim i
' For i = 1 To nLen
' Response.Write aTree(i) & "<br>"
' Next
Call DBConnEnd()
Function GetRescordCount()
GetRescordCount = oConn.Execute( " select count(id) from " & sTableName)( 0 )
End Function
Sub GetPowerName(s_Id)
Dim n_ParentId, j, oRs
Set oRs = Server.CreateObject( " ADODB.Recordset " )
sSql = " select id,PowerName,Layer from " & sTableName & " where ParentId= " & s_Id
oRs.Open sSql, oConn, 0 , 1
Do While Not oRs.Eof
For j = 1 To oRs( " Layer " )
response.write " "
Next
aTree(nCurrent) = oRs( " PowerName " )
response.write aTree(nCurrent) & " <br> "
nCurrent = nCurrent + 1
n_ParentId = oRs( " id " )
Call GetPowerName(n_ParentId)
oRs.MoveNext
Loop
oRs.Close
Set oRs = Nothing
End Sub
Sub DBConnBegin()
' 如果数据库对象已打开,不要再打开
If IsObject (oConn) = True Then Exit Sub
' 你可以不需要打开数据库连接对象而直接打开记录集对象,但如果你需要打开多个记录集对象的话,效率是很低的。
' 如果你不创建一个数据库连接对象,ADO会在每个记录集打开时自动创建一个新的数据库连接对象,就算你用的是相同的SQL语句。
Set oConn = Server.CreateObject( " ADODB.Connection " )
On Error Resume Next
' Provider=SQLOLEDB.1;Server=(local);Initial Catalog =cx_soft;Integrated Security=SSPI;
' Provider=SQLOLEDB.1;Server=(local);Initial Catalog =cx_soft;Trusted_Connection=yes;
oConn.Open " Provider=sqloledb.1;Data Source=(local);Initial Catalog=AspNetTest;User Id=sa;Password=; "
If Err.Number > 0 Then
' 完全地退出正在运行的脚本
Response.End
End If
' 创建一个记录集
End Sub
Sub DBConnEnd()
On Error Resume Next
oRs.Close
Set oRs = Nothing
oConn.Close
Set oConn = Nothing
End Sub
% >
asp.net代码:
( 请注意:asp.net1.1中用同一个Connection,在前一个DataReader没有Close情况下再创建DataReader会出现错误提示:已有打开的与此连接相关联的 DataReader,必须首先将它关闭
我的做法是每次都创建一个Connection,很浪费资源,不知道有没其他好办法.
)
1
using
System;
2 using System.Collections;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Web;
7 using System.Web.SessionState;
8 using System.Web.UI;
9 using System.Web.UI.WebControls;
10 using System.Web.UI.HtmlControls;
11 using System.Data.SqlClient;
12
13 namespace AspNetTest.Common
14 {
15 /**//// <summary>
16 /// tree 的摘要说明。
17 /// </summary>
18
19 public class tree : System.Web.UI.Page
20 {
21 private string tablename = "tree";
22 int current = 0;
23 int len = 0;
24 string[] arrPowerName;
25 string ConnectionString;
26 public tree()
27 {
28 ConnectionString = System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"];
29 len = GetRecordCount();
30 arrPowerName = new string[len];
31 }
32 private void Page_Load(object sender, System.EventArgs e)
33 {
34
35 GetPowerName(0);
36 //CloseDbConnection();
37 //ResponseArray();
38 // 在此处放置用户代码以初始化页面
39 }
40 private void GetPowerName(int _ParentId)
41 {
42 int Id;
43 string PowerName;
44 string sql = "select Id,PowerName,Layer from " + tablename + " where ParentId=" + _ParentId;
45 try
46 {
47 SqlConnection conn = new SqlConnection(ConnectionString);
48 conn.Open();
49 SqlCommand cmd = new SqlCommand(sql, conn);
50 SqlDataReader dr = cmd.ExecuteReader();
51 while(dr.Read())
52 {
53 for(int j=0; j<int.Parse(dr["Layer"].ToString()); j++)
54 {
55 Response.Write(" ");
56 }
57 PowerName = dr["PowerName"].ToString();
58 Response.Write(PowerName + "<br>");
59 arrPowerName[current++] = PowerName;
60 Id = int.Parse(dr["Id"].ToString());
61 GetPowerName(Id);
62 }
63 dr.Close();
64 conn.Close();
65 }
66 catch(Exception ex)
67 {
68 Response.Write(ex.ToString());
69 }
70 }
71 private void ResponseArray()
72 {
73 int i;
74 for(i=0; i<len; i++)
75 {
76 Response.Write(arrPowerName[i] + "<br>");
77 }
78 }
79 private void CloseDbConnection()
80 {
81 //conn.Close();
82 }
83 private int GetRecordCount()
84 {
85 SqlConnection conn = new SqlConnection(ConnectionString);
86 string sql = "select count(id) from " + tablename;
87 conn.Open();
88 SqlCommand cmd = new SqlCommand(sql, conn);
89 int count = int.Parse(cmd.ExecuteScalar().ToString());
90 conn.Close();
91 return count;
92 }
93
94 Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
95 override protected void OnInit(EventArgs e)
96 {
97 //
98 // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
99 //
100 InitializeComponent();
101 base.OnInit(e);
102 }
103
104 /**//// <summary>
105 /// 设计器支持所需的方法 - 不要使用代码编辑器修改
106 /// 此方法的内容。
107 /// </summary>
108 private void InitializeComponent()
109 {
110 this.Load += new System.EventHandler(this.Page_Load);
111
112 }
113 #endregion
114 }
115}
116
2 using System.Collections;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Web;
7 using System.Web.SessionState;
8 using System.Web.UI;
9 using System.Web.UI.WebControls;
10 using System.Web.UI.HtmlControls;
11 using System.Data.SqlClient;
12
13 namespace AspNetTest.Common
14 {
15 /**//// <summary>
16 /// tree 的摘要说明。
17 /// </summary>
18
19 public class tree : System.Web.UI.Page
20 {
21 private string tablename = "tree";
22 int current = 0;
23 int len = 0;
24 string[] arrPowerName;
25 string ConnectionString;
26 public tree()
27 {
28 ConnectionString = System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"];
29 len = GetRecordCount();
30 arrPowerName = new string[len];
31 }
32 private void Page_Load(object sender, System.EventArgs e)
33 {
34
35 GetPowerName(0);
36 //CloseDbConnection();
37 //ResponseArray();
38 // 在此处放置用户代码以初始化页面
39 }
40 private void GetPowerName(int _ParentId)
41 {
42 int Id;
43 string PowerName;
44 string sql = "select Id,PowerName,Layer from " + tablename + " where ParentId=" + _ParentId;
45 try
46 {
47 SqlConnection conn = new SqlConnection(ConnectionString);
48 conn.Open();
49 SqlCommand cmd = new SqlCommand(sql, conn);
50 SqlDataReader dr = cmd.ExecuteReader();
51 while(dr.Read())
52 {
53 for(int j=0; j<int.Parse(dr["Layer"].ToString()); j++)
54 {
55 Response.Write(" ");
56 }
57 PowerName = dr["PowerName"].ToString();
58 Response.Write(PowerName + "<br>");
59 arrPowerName[current++] = PowerName;
60 Id = int.Parse(dr["Id"].ToString());
61 GetPowerName(Id);
62 }
63 dr.Close();
64 conn.Close();
65 }
66 catch(Exception ex)
67 {
68 Response.Write(ex.ToString());
69 }
70 }
71 private void ResponseArray()
72 {
73 int i;
74 for(i=0; i<len; i++)
75 {
76 Response.Write(arrPowerName[i] + "<br>");
77 }
78 }
79 private void CloseDbConnection()
80 {
81 //conn.Close();
82 }
83 private int GetRecordCount()
84 {
85 SqlConnection conn = new SqlConnection(ConnectionString);
86 string sql = "select count(id) from " + tablename;
87 conn.Open();
88 SqlCommand cmd = new SqlCommand(sql, conn);
89 int count = int.Parse(cmd.ExecuteScalar().ToString());
90 conn.Close();
91 return count;
92 }
93
94 Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
95 override protected void OnInit(EventArgs e)
96 {
97 //
98 // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
99 //
100 InitializeComponent();
101 base.OnInit(e);
102 }
103
104 /**//// <summary>
105 /// 设计器支持所需的方法 - 不要使用代码编辑器修改
106 /// 此方法的内容。
107 /// </summary>
108 private void InitializeComponent()
109 {
110 this.Load += new System.EventHandler(this.Page_Load);
111
112 }
113 #endregion
114 }
115}
116
遍历结果:
代码下载:
asp代码: /Files/jiny-z/tree(asp).rar
asp.net代码: /Files/jiny-z/tree(asp.net).rar
*********************************************************
根据chill ,flower.b的提示,修改了代码。
原来:asp/asp.net代码中都是在数据集中循环,效率较低.。
现在:asp代码改为在数组中循环,asp.net代码改为在DataTable中循环。
*********************************************************
asp代码:
<
%@ Language
=
VBScript%
>
< % Option Explicit % >
< %
Dim oConn, oRs, sSql
Dim aTree
Call FillArrayFromRs()
Call blTreeArray( 0 )
Sub FillArrayFromRs()
Dim s_TableName
s_TableName = " tree "
Call DBConnBegin()
Set oRs = Server.CreateObject( " ADODB.Recordset " )
sSql = " select Id,PowerName,Layer,ParentId from " & s_TableName
oRs.Open sSql, oConn, 0 , 1
aTree = oRs.GetRows()
' response.write ubound(aTree, 2)
oRs.Close
Call DBConnEnd()
End Sub
Sub blTreeArray(n_ParentId)
Dim row, rows
Dim n_NextParentId
Dim n_Space
rows = UBound (aTree, 2 )
for row = 0 To rows
If aTree( 3 , row) = n_ParentId Then
for n_Space = 1 To aTree( 2 , row)
Response.Write " "
Next
Response.Write aTree( 1 , row) & " <br> "
n_NextParentId = aTree( 0 , row)
blTreeArray(n_NextParentId)
End If
Next
End Sub
Sub DBConnBegin()
' 如果数据库对象已打开,不要再打开
If IsObject (oConn) = True Then Exit Sub
' 你可以不需要打开数据库连接对象而直接打开记录集对象,但如果你需要打开多个记录集对象的话,效率是很低的。
' 如果你不创建一个数据库连接对象,ADO会在每个记录集打开时自动创建一个新的数据库连接对象,就算你用的是相同的SQL语句。
Set oConn = Server.CreateObject( " ADODB.Connection " )
On Error Resume Next
' Provider=SQLOLEDB.1;Server=(local);Initial Catalog =cx_soft;Integrated Security=SSPI;
' Provider=SQLOLEDB.1;Server=(local);Initial Catalog =cx_soft;Trusted_Connection=yes;
oConn.Open " Provider=sqloledb.1;Data Source=(local);Initial Catalog=AspNetTest;User Id=sa;Password=; "
If Err.Number > 0 Then
' 完全地退出正在运行的脚本
Response.End
End If
' 创建一个记录集
End Sub
Sub DBConnEnd()
On Error Resume Next
oRs.Close
Set oRs = Nothing
oConn.Close
Set oConn = Nothing
End Sub
% >
< % Option Explicit % >
< %
Dim oConn, oRs, sSql
Dim aTree
Call FillArrayFromRs()
Call blTreeArray( 0 )
Sub FillArrayFromRs()
Dim s_TableName
s_TableName = " tree "
Call DBConnBegin()
Set oRs = Server.CreateObject( " ADODB.Recordset " )
sSql = " select Id,PowerName,Layer,ParentId from " & s_TableName
oRs.Open sSql, oConn, 0 , 1
aTree = oRs.GetRows()
' response.write ubound(aTree, 2)
oRs.Close
Call DBConnEnd()
End Sub
Sub blTreeArray(n_ParentId)
Dim row, rows
Dim n_NextParentId
Dim n_Space
rows = UBound (aTree, 2 )
for row = 0 To rows
If aTree( 3 , row) = n_ParentId Then
for n_Space = 1 To aTree( 2 , row)
Response.Write " "
Next
Response.Write aTree( 1 , row) & " <br> "
n_NextParentId = aTree( 0 , row)
blTreeArray(n_NextParentId)
End If
Next
End Sub
Sub DBConnBegin()
' 如果数据库对象已打开,不要再打开
If IsObject (oConn) = True Then Exit Sub
' 你可以不需要打开数据库连接对象而直接打开记录集对象,但如果你需要打开多个记录集对象的话,效率是很低的。
' 如果你不创建一个数据库连接对象,ADO会在每个记录集打开时自动创建一个新的数据库连接对象,就算你用的是相同的SQL语句。
Set oConn = Server.CreateObject( " ADODB.Connection " )
On Error Resume Next
' Provider=SQLOLEDB.1;Server=(local);Initial Catalog =cx_soft;Integrated Security=SSPI;
' Provider=SQLOLEDB.1;Server=(local);Initial Catalog =cx_soft;Trusted_Connection=yes;
oConn.Open " Provider=sqloledb.1;Data Source=(local);Initial Catalog=AspNetTest;User Id=sa;Password=; "
If Err.Number > 0 Then
' 完全地退出正在运行的脚本
Response.End
End If
' 创建一个记录集
End Sub
Sub DBConnEnd()
On Error Resume Next
oRs.Close
Set oRs = Nothing
oConn.Close
Set oConn = Nothing
End Sub
% >
asp.net代码:
using
System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace AspNetTest.Common
{
/**//// <summary>
/// tree_DataTable 的摘要说明。
/// </summary>
public class tree_DataTable : System.Web.UI.Page
{
private DataTable dtPowerTree = new DataTable();
const string tablename = "tree";
private void Page_Load(object sender, System.EventArgs e)
{
FillTreeDataTable();
blTreeDataTable(0);
dtPowerTree.Clear();
// 在此处放置用户代码以初始化页面
}
private void FillTreeDataTable()
{
string ConnectionString = System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"];
SqlConnection conn = new SqlConnection(ConnectionString);
SqlDataAdapter da = new SqlDataAdapter("select Id,PowerName,Layer,ParentId from " + tablename, conn);
da.Fill(dtPowerTree);
}
private void blTreeDataTable(int _ParentId)
{
string filter = "ParentId=" + _ParentId;
string sort = "Id ASC";
DataRow[] drs = dtPowerTree.Select(filter, sort);
for(int i=0; i<drs.Length; i++)
{
if(Convert.ToInt32(drs[i][3]) == _ParentId)
{
int Id = Convert.ToInt32(drs[i][0]);
string PowerName = drs[i][1].ToString();
int Layer = Convert.ToInt32(drs[i][2]);
for(int space=1; space<=Layer; space++)
{
Page.Response.Write(" ");
}
Page.Response.Write(PowerName + "<br>");
blTreeDataTable(Id);
}
}
}
Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/**//// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
}
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace AspNetTest.Common
{
/**//// <summary>
/// tree_DataTable 的摘要说明。
/// </summary>
public class tree_DataTable : System.Web.UI.Page
{
private DataTable dtPowerTree = new DataTable();
const string tablename = "tree";
private void Page_Load(object sender, System.EventArgs e)
{
FillTreeDataTable();
blTreeDataTable(0);
dtPowerTree.Clear();
// 在此处放置用户代码以初始化页面
}
private void FillTreeDataTable()
{
string ConnectionString = System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"];
SqlConnection conn = new SqlConnection(ConnectionString);
SqlDataAdapter da = new SqlDataAdapter("select Id,PowerName,Layer,ParentId from " + tablename, conn);
da.Fill(dtPowerTree);
}
private void blTreeDataTable(int _ParentId)
{
string filter = "ParentId=" + _ParentId;
string sort = "Id ASC";
DataRow[] drs = dtPowerTree.Select(filter, sort);
for(int i=0; i<drs.Length; i++)
{
if(Convert.ToInt32(drs[i][3]) == _ParentId)
{
int Id = Convert.ToInt32(drs[i][0]);
string PowerName = drs[i][1].ToString();
int Layer = Convert.ToInt32(drs[i][2]);
for(int space=1; space<=Layer; space++)
{
Page.Response.Write(" ");
}
Page.Response.Write(PowerName + "<br>");
blTreeDataTable(Id);
}
}
}
Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/**//// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
}