本文介绍如何在SQL Server中查询和展示树形层次数据表,特别是使用存储过程来处理父子ID字段的关系。文章提供了一个存储过程usp_treeview的实现,该过程能在查询结果中呈现出先父后子的顺序,适用于数值型和字符型的父子ID字段,且能在SQL Server 2000环境中运行。尽管存在一些局限性,如未详述算法和扩展问题,但这是一个实用的开始。
----------------------------------------------------------------------------------------------------------------------------------------- --显示树型结构数据集 --CREATE: 项前,2008-4-14 --EXAMPLE: --DECLARE @TABLE NVARCHAR(50),@PIDCOL NVARCHAR(50),@IDCOL NVARCHAR(50),@DESCCOL NVARCHAR(50) --SELECT @TABLE ='Northwind..Employees',@PIDCOL ='ReportsTo',@IDCOL ='EmployeeID',@DESCCOL ='LastName' --EXEC USP_TREEVIEW @TABLE ,@PIDCOL ,@IDCOL ,@DESCCOL ----------------------------------------------------------------------------------------------------------------------------------------- CREATEPROCEDURE USP_TREEVIEW @TABLENVARCHAR(50) --表名 ,@PIDCOLNVARCHAR(50) --父结点标识字段名 ,@IDCOLNVARCHAR(50) --子结点标识字段名 ,@DESCCOLNVARCHAR(50) --显示节点标签字段 AS BEGIN DECLARE@SQLVARCHAR(8000) SELECT@SQL=' DECLARE @TMP TABLE( [PID_NUM] [INT] NULL, [ID_NUM] [int] IDENTITY (1, 1) NOT NULL , ['+@PIDCOL+'] [nvarchar] (20) NULL , ['+@IDCOL+'] [nvarchar] (20) NOT NULL , ['+@DESCCOL+'] [ntext] NULL, PATH NVARCHAR(1000) NULL, NEXT_PARENTID INT NULL, PRE_PARENTID INT NULL, PATHCHAR NVARCHAR(1000) DEFAULT('''') NULL, ISFIRST BIT DEFAULT(1) NULL ) INSERT @TMP (['+@PIDCOL+'],['+@IDCOL+'],['+@DESCCOL+']) SELECT ['+@PIDCOL+'],['+@IDCOL+'],['+@DESCCOL+'] FROM '+@TABLE+' order by '+@PIDCOL+','+@IDCOL+' UPDATE A SET PID_NUM=B.ID_NUM,PATH=CAST(A.ID_NUM AS NVARCHAR),NEXT_PARENTID=B.ID_NUM FROM @TMP A LEFT JOIN @TMP B ON A.'+@PIDCOL+'=B.'+@IDCOL+' WHILE @@ROWCOUNT!=0 UPDATE A SET A.PATH=ISNULL(CAST(A.NEXT_PARENTID AS NVARCHAR)+''.'','''')+A.PATH ,A.PATHCHAR=CASE WHEN A.ISFIRST=1 THEN CASE WHEN not exists (select * from @TMP where PID_NUM=A.NEXT_PARENTID and ID_NUM>A.ID_NUM ) THEN ''└'' + replicate(''─'', 2) + A.PATHCHAR ELSE ''├'' +replicate(''─'', 2) + A.PATHCHAR END ELSE CASE WHEN exists (select * from @TMP where PID_NUM=A.NEXT_PARENTID and ID_NUM>( select ID_NUM from @TMP where ID_NUM=A.PRE_PARENTID) ) THEN ''│'' + replicate('''', 2) +A.PATHCHAR ELSE replicate('''', 3) +A.PATHCHAR END END ,A.PRE_PARENTID=A.NEXT_PARENTID ,A.NEXT_PARENTID=B.PID_NUM ,A.ISFIRST=0 FROM @TMP A LEFT JOIN @TMP B ON A.NEXT_PARENTID=B.ID_NUM WHERE A.NEXT_PARENTID IS NOT NULL --SELECT * FROM @TMP ORDER BY PATH SELECT PATHCHAR+CAST(['+@DESCCOL+'] AS NVARCHAR) AS '+'[Label_'+@DESCCOL+'],['+@IDCOL+'],['+@PIDCOL+'] FROM @TMP ORDER BY PATH ' --print (@SQL) exec( @SQL) END