`
LubinJava
  • 浏览: 1677 次
  • 性别: Icon_minigender_1
  • 来自: 福建莆田
文章分类
社区版块
存档分类

sqlserver 下用函数实现 oracle 的树查询( start with connect by ) 功能

阅读更多
/* SQLServer2005下自定义函数实现类似Oracle的树查询(start with) 功能 */
/* 已知信息 */
--实体树结点表的结构及初始数据如下:
CREATE TABLE T_NODE (
NODE_ID INT, --结点ID
NODE_NAME VARCHAR(255), --结点名称
P_NODE INT --父结点ID
)
INSERT INTOT_NODEVALUES (1,'根结点',0);
INSERT INTOT_NODEVALUES (2,'结点A',1);
INSERT INTOT_NODEVALUES (3,'结点B',1);
INSERT INTOT_NODEVALUES (4,'结点C',1);
INSERT INTOT_NODEVALUES (5,'结点A_1',2);
INSERT INTOT_NODEVALUES (6,'结点A_2',2);
INSERT INTOT_NODEVALUES (7,'结点A_3',2);
INSERT INTOT_NODEVALUES (8,'结点A_1_A',5);
INSERT INTOT_NODEVALUES (9,'结点A_1_B',5);
INSERT INTOT_NODEVALUES (10,'结点B_1',3);
INSERT INTOT_NODEVALUES (11,'结点B_2',3);
INSERT INTOT_NODEVALUES (12,'结点B_3',3);
/* ** ======================= ** */



/* 函数的实现 _方法1 * 普通的循环查询树 测试通过 ********
* 优点:快速遍历.
* 缺点:树的插入不是逐条插入的,而是按树的查询等级的顺序插入的
* ******* */
----创建函数---------
--DROP FUNCTION F_NODE_TREE
-- =============================================
-- Author: <liujianbin>
-- Create date: 2011-06-12
-- Description: 循环查询T_NODE树
-- =============================================
CREATE FUNCTION F_NODE_TREE(
@fId varchar(10)
)
RETURNS
@TMP_NODE_TREE TABLE(
ID INT, --结点ID
FID INT, --父结点ID
LEVEL INT --结点等级
)
AS
BEGIN
--定义变量
DECLARE @tmpLevel INT
--初始化
SET @tmpLevel=1
--插入第一个结点
INSERT @TMP_NODE_TREE SELECT T.NODE_ID, T.P_NODE, @tmpLevel FROM T_NODE T WHERE T.P_NODE=@fId
--插入数据不是空行,则循环插入下一级的结点数据
WHILE @@rowcount > 0
BEGIN
--级别加1
SET @tmpLevel=@tmpLevel+1
--根据上一级查询出来的父结点信息插入下一级数据
INSERT @TMP_NODE_TREE SELECT T.NODE_ID, T.P_NODE, @tmpLevel FROM T_NODE T ,@TMP_NODE_TREE b WHERE b.ID=T.P_NODE AND b.LEVEL=@tmpLevel-1
END
RETURN
END
-----------------------------------------
------调用示例 ---------------
SELECT T.* FROM F_NODE_TREE(0) T
/* ***** 方法1 结束 ***** */






/* 函数的实现 _方法2 ********** 逐条递归查询树 测试通过 ********
* 优点: 逐条递归查询插入,确保树的显示序列是按递归顺序排列(SID)
* 缺点: 性能上较 方法1 的慢 (查询大量数据的时候会比较明显),递归有32级限制.
* ******* */
----创建函数---------
--DROP FUNCTION F_NODE_TREE_REC
-- =============================================
-- Author: <liujianbin>
-- Create date: 2011-06-12
-- Description: 递归查询T_NODE树
-- =============================================
CREATE FUNCTION F_NODE_TREE_REC(
@fId VARCHAR(12) , --父结点ID
@level BIGINT , --当前级别,默认1
@sId BIGINT --当前插入序列,默认1
)
RETURNS
@TMP_TREE_TABLE TABLE(
ID BIGINT, --结点ID
FID BIGINT, --父结点ID
LEVEL BIGINT, --结点等级
SID BIGINT --插入序列
)
AS
BEGIN
-- 局部变量定义
DECLARE @tid BIGINT --临时ID
DECLARE @tfid BIGINT --临时父ID
DECLARE @sortId BIGINT --排列顺序ID
DECLARE @subId BIGINT --子结点ID
-- 本地游标定义
DECLARE @cur CURSOR
SET @cur = CURSOR LOCAL FOR SELECT NODE_ID,P_NODE from T_NODE where P_NODE=@fId
--数据初始化
SET @sortId = @sId
IF @sortId IS NULL OR @sortId < 1
SET @sortId = 1
if @level IS NULL OR @level < 0
SET @level = 0
SET @level = @level+1
SET @subId = NULL
-- 打开游标
OPEN @cur
FETCH NEXT FROM @cur INTO @tid,@tfid
WHILE @@rowcount > 0
BEGIN
INSERT INTO @TMP_TREE_TABLE VALUES(@tid,@tfid,@level, @sortId )
--插入顺序序列+1
SET @sortId = @sortId+1
--取当前结点的子结点,用来判断是否含有子结点
SELECT @subId = (SELECT TOP 1 T.NODE_ID FROM T_NODE T WHERE T.P_NODE=@tid)
--如果有子结点,则开始递归插入
IF @subId IS NOT NULL
BEGIN
-- 树形结构数据递归收集到建立的临时表中
INSERT @TMP_TREE_TABLE SELECT * from dbo.F_NODE_TREE_REC(@tid,@level,@sortId)
--设置下一个循环的序列为递归后的总合加当前值
SELECT @sortId =@sortId + (SELECT TOP 1 COUNT(*) FROM dbo.F_NODE_TREE_REC(@tid,@level,@sortId) )
END
--游标下移一位,进入下一个循环
FETCH NEXT FROM @cur INTO @tid,@tfid
END
CLOSE @cur
DEALLOCATE @cur
RETURN
END
----------------------------------------------
----调用示例----
SELECT T.* FROM F_NODE_TREE_REC(0,NULL,NULL) T ORDER BY T.SID
/* ***** 方法2 结束 **** */
2
2
分享到:
评论
1 楼 jinsedeme 2012-02-01  
很好很强大

相关推荐

    Oracle和SqlServer语法区别

    3. 用相应的SqlServer函数替代Oracle函数。 4. 检查所有的比较运算符。 5. 用“+”字符串串联运算符代替“||”字符串串联运算符。 6. 用Transact-SQL程序代替PL/SQL程序。 7. 把所有PL/SQL游标改为非游标SELECT语句...

    ORACLE和SQL Server的语法区别

    - 用相应的SQL Server函数替代Oracle函数。 #### 五、字符串连接 - **Oracle:** Oracle使用`||`作为字符串连接运算符。 ```sql SELECT 'Hello' || 'World' AS Result; ``` - **SQL Server:** SQL Server使用...

    Sql Server与Oracle的区别

    - **SELECT语句**:尽管基本语法相似,但Oracle支持特定的优化提示和集合运算符如START WITH和CONNECT BY,以及INTERSECT和MINUS,这些在Sql Server中需要通过其他方式实现,比如使用EXISTS和NOT EXISTS子句。...

    Oracle和SQL_Server的语法区别

    - Oracle 的 `START WITH U CONNECT BY` 用于创建层次查询,SQL Server 可以通过递归公共表表达式(CTE)或存储过程实现类似功能。 - Oracle 支持 `INTERSECT` 和 `MINUS` 集合运算符,而 SQL Server 用 `EXISTS` 和...

    ORACLE与SQLSERVER语法差异分析

    - 在SQL SERVER中,递归查询通常使用`WITH`子句创建公共表表达式(CTE),结合`UNION ALL`和`JOIN`来实现。如示例所示,`cte_root`或`cte_child`定义递归起点,`connect by ID=prior ParentID`表示递归路径。 - ...

    数据库设计之递归树查询

    本文将深入探讨如何通过递归查询来解决这类问题,并着重讲解使用`WITH`语句来实现递归查询的方法,适用于多种数据库系统,如MySQL、PostgreSQL、SQL Server等。 一、理解递归查询 递归查询是一种在数据库中遍历层级...

    oracle和SQL的语法区别

    在 SELECT 语句方面,虽然基本结构相似,但 Oracle 的特定功能如 `START WITH` 和 `CONNECT BY` 用于构建层次查询,在 SQL Server 中可以通过递归查询或存储过程实现。此外,Oracle 的 `INTERSECT` 和 `MINUS` 集合...

    sql查询某个parentid下的所有childid

    - **使用其他函数**:结合其他Oracle函数(如`SYS_CONNECT_BY_PATH`)可以获得更丰富的层次结构信息,例如获取整个路径等。 通过以上介绍,我们可以看出,Oracle的`CONNECT BY`特性是非常强大的工具,能够有效地...

    SQL_Server,Oracle,DB2数据库SQL语句比较

    标题与描述均聚焦于SQL Server, Oracle, 和DB2数据库中的SQL语句比较,这是一个对IT专业人士特别是数据库管理员(DBA)、开发人员以及对数据库技术感兴趣的人来说极为实用的主题。以下是对给定文件中提及的关键知识点...

    解决Oracle没有WM_CONCAT函数.zip

    在Oracle数据库中,WM_CONCAT是一个非常实用的聚合函数,用于将一组字符串连接成一个单一的字符串,类似于SQL Server中的STRING_AGG或MySQL中的GROUP_CONCAT。然而,Oracle官方并没有提供这个函数,它是一个第三方...

    树形查询带记录数量

    在进行树形查询时,我们通常会用到递归SQL查询或者利用数据库提供的特定功能,如Oracle的CONNECT BY,MySQL的WITH RECURSIVE,或者SQL Server的Hierarchical Queries。这些语法允许我们构建一个层次结构,从根节点...

    一种MySQL数据库SQL递归查询的研究与实现.pdf

    CONNECT BY PRIOR`子句直接支持递归查询,而SQL Server 2005及以上版本则利用公共表表达式(CTE)的递归调用来实现。POSTgreSQL同样支持CTE子查询进行递归。这些数据库允许在SQL语句中直接对子查询进行递归调用,...

    SQL最佳实践

    - **CONNECT_BY在DB2、SQL Server中的实现**:虽然不同数据库系统的实现方式略有差异,但核心思想相似。 - **CONNECT_BY_ROOT**:返回层次结构的根节点。 - **SYS_CONNECT_BY_PATH()**:用于构建层次路径。 - **...

    分页显示Oracle数据库记录的PHP类

    2. **连接方法**:`db_connect()`使用`OCILogon`函数建立到Oracle数据库的连接。 ```php function db_connect(){ $conn = OCILogon($this-&gt;user,$this-&gt;pwd,$this-&gt;database); return $conn; } ``` 3. **执行...

    Oracle常用操作(项目中积累的经验)

    以下是一个使用`START WITH`, `CONNECT BY PRIOR`, `LEVEL`, `CONNECT_BY_ROOT`, `CONNECT_BY_ISLEAF`的例子: ```sql SELECT LEVEL treelevel, CONNECT_BY_ISLEAF isleaf, LTRIM (SYS_CONNECT_BY_PATH (cost_code,...

    常用sql语句的收集

    在Oracle中,使用`START WITH`和`CONNECT BY`子句进行层次查询或递归查询。例如,查询设备名称及其所属公司的递归关系: ```sql WITH RECURSIVE device_hierarchy AS ( SELECT d.device_name, c.company_name ...

    韩顺平oracle学习笔记

    2.最好学习过一门别的数据库(sql server,mysql , access) 教程推荐:oracle使用教程, 深入浅出oracle 记住:欲速则不达,做任何事情要遵循他的规律,循序渐进,信心很重要 成为一个oracle高手过程:理解小知识点-&gt;...

    oracle常用语法

    在Oracle中,使用 `START WITH` 和 `CONNECT BY PRIOR` 子句来执行此类查询。 **语法示例**: ```sql SELECT * FROM sys_areas START WITH area_name = 'ɳ' CONNECT BY PRIOR area_id = up_area_id ORDER BY area_...

Global site tag (gtag.js) - Google Analytics