当前位置: 首页 > news >正文

在父子关系表中获取子孙后代结点数据SQL查询算法

常见于目录表结构中(树状结构)如项目目录表,根据目录Id获取其属下所有子结点:

CREATE    PROCEDURE [dbo].[pGetDescendedPhysicalItemCatalogs](
    @PhysicalItemCatalogId int 
)
AS
set nocount on

BEGIN TRY
    IF NOT EXISTS (SELECT * FROM [tempdb].sys.objects WHERE name = '##PhysicalItemCatalog')
        CREATE TABLE ##PhysicalItemCatalog(
            [PhysicalItemCatalogId] [int] ,
            [Name] [nvarchar](50) NOT NULL ,
            [MnemonicCode] [nvarchar](10) NOT NULL ,
            [ParentId] [int] NOT NULL ,
            [IsDeleted] [bit] NOT NULL ,
            [IsValid] [bit] NOT NULL ,
            [PhysicalSpecialtyId] [int] NOT NULL ,
            [Handled] [bit] NOT NULL default 0
        )

    INSERT ##PhysicalItemCatalog(PhysicalItemCatalogId, Name, MnemonicCode, ParentId, IsDeleted, IsValid, PhysicalSpecialtyId)
    SELECT PhysicalItemCatalogId, Name, MnemonicCode, ParentId, IsDeleted, IsValid, PhysicalSpecialtyId 
    FROM entity.PhysicalItemCatalog with(nolock) WHERE PhysicalItemCatalogId > -1 AND ParentId = @PhysicalItemCatalogId
    
    DECLARE @catalogId int 
    SELECT TOP 1 @catalogId = PhysicalItemCatalogId FROM ##PhysicalItemCatalog WHERE Handled = 0
    IF @catalogId IS NOT NULL 
    begin
        update ##PhysicalItemCatalog set Handled = 1 where PhysicalItemCatalogId = @catalogId
        exec [dbo].[pGetDescendedPhysicalItemCatalogs] @catalogId
    end
    ELSE
    begin
        SELECT * FROM ##PhysicalItemCatalog
        DROP TABLE ##PhysicalItemCatalog
    end
END TRY
BEGIN CATCH
    IF EXISTS (SELECT * FROM [tempdb].sys.objects WHERE name = '##PhysicalItemCatalog')
        DROP TABLE ##PhysicalItemCatalog
END CATCH

set nocount off

 

使用的场景(譬如更新与根目录不一致的字段值):

CREATE    PROCEDURE [dbo].[pRecalPhysicalItemCatalogsSpecialty]
AS
set nocount on

declare @catalogId int
declare @specialtyId int
DECLARE @catalog TABLE (
    [PhysicalItemCatalogId] [int] ,
    [Name] [nvarchar](50) NOT NULL ,
    [MnemonicCode] [nvarchar](10) NOT NULL ,
    [ParentId] [int] NOT NULL ,
    [IsDeleted] [bit] NOT NULL ,
    [IsValid] [bit] NOT NULL ,
    [PhysicalSpecialtyId] [int] NOT NULL ,
    [Handled] [bit] NOT NULL default 0
)

DECLARE my_cursor CURSOR FOR
select PhysicalItemCatalogId, PhysicalSpecialtyId from entity.PhysicalItemCatalog where parentId = -1
and PhysicalItemCatalogId in (select ParentId from entity.PhysicalItemCatalog where ParentId > -1)
OPEN my_cursor;
FETCH NEXT FROM my_cursor INTO @catalogId, @specialtyId;
WHILE @@FETCH_STATUS = 0
BEGIN
    insert into @catalog exec [dbo].[pGetDescendedPhysicalItemCatalogs] @catalogId

    UPDATE t
    SET PhysicalSpecialtyId = @specialtyId 
    FROM entity.PhysicalItemCatalog t, @catalog a
    WHERE t.PhysicalItemCatalogId = a.PhysicalItemCatalogId

    delete @catalog

    FETCH NEXT FROM my_cursor INTO @catalogId, @specialtyId;
END;
CLOSE my_cursor;
DEALLOCATE my_cursor;

set nocount off


上述可能存在嵌套不能超过32层的错误问题,修改将查询结果保存到临时表中:

/*
* TEST SCRIPT:
    declare @catalogId int
    DECLARE my_cursor CURSOR FOR
    select MedicineCatalogId from mmat.MedicineCatalog with(nolock) WHERE MedicineCatalogId > -1 AND ParentCatalogId = -1

    OPEN my_cursor;
    FETCH NEXT FROM my_cursor INTO @catalogId;
    WHILE @@FETCH_STATUS = 0
    BEGIN
        exec [dbo].[pGetChildrenMedicineCatalogs] @catalogId
        FETCH NEXT FROM my_cursor INTO @catalogId;
    END;

    CLOSE my_cursor;
    DEALLOCATE my_cursor;
    
    IF EXISTS (SELECT * FROM [tempdb].sys.objects WHERE name = '##MedicineCatalog')
    BEGIN
        SELECT * FROM ##MedicineCatalog ORDER BY ParentCatalogId, MedicineCatalogId
        DROP TABLE ##MedicineCatalog
    END
*/
CREATE    PROCEDURE [dbo].[pGetChildrenMedicineCatalogs](
    @MedicineCatalogId int
)

AS
set nocount on
IF NOT EXISTS (SELECT * FROM [tempdb].sys.objects WHERE name = '##MedicineCatalog')
    CREATE TABLE ##MedicineCatalog(
        [MedicineCatalogId] [int] ,
        [Name] [nvarchar](50) NOT NULL ,
        [SubstanceClassCodeId] [tinyint] NOT NULL ,
        [SpellCode] [nvarchar](20) NULL ,
        [ParentCatalogId] [int] NOT NULL ,
        [IsDeleted] [bit] NOT NULL ,
        [Handled] [bit] NOT NULL default 0
    )

DECLARE @MedicineCatalog TABLE (
    [RID] INT IDENTITY(1,1),
    [MedicineCatalogId] [int] ,
    [Name] [nvarchar](50) NOT NULL ,
    [SubstanceClassCodeId] [tinyint] NOT NULL ,
    [SpellCode] [nvarchar](20) NULL ,
    [ParentCatalogId] [int] NOT NULL ,
    [IsDeleted] [bit] NOT NULL ,
    [Handled] [bit] NOT NULL default 0
)
 
INSERT ##MedicineCatalog(MedicineCatalogId, Name, SubstanceClassCodeId, SpellCode, ParentCatalogId, IsDeleted)
SELECT MedicineCatalogId, Name, SubstanceClassCodeId, SpellCode, ParentCatalogId, IsDeleted 
FROM mmat.MedicineCatalog with(nolock) WHERE MedicineCatalogId > -1 AND ParentCatalogId = @MedicineCatalogId

declare @count INT

INSERT @MedicineCatalog(MedicineCatalogId, Name, SubstanceClassCodeId, SpellCode, ParentCatalogId, IsDeleted)
SELECT MedicineCatalogId, Name, SubstanceClassCodeId, SpellCode, ParentCatalogId, IsDeleted 
FROM mmat.MedicineCatalog with(nolock) WHERE MedicineCatalogId > -1 AND ParentCatalogId = @MedicineCatalogId

SELECT @count = @@ROWCOUNT;
declare @catalogId INT
declare @rid INT
SET @rid = 1;
WHILE @rid <= @count
BEGIN
    SELECT @catalogId = MedicineCatalogId FROM @MedicineCatalog mc WHERE RID = @rid;
    update ##MedicineCatalog set Handled = 1 where MedicineCatalogId = @catalogId
    exec [dbo].[pGetChildrenMedicineCatalogs] @catalogId

    SET @rid = @rid + 1;
END

set nocount off
GO

 

 

转载于:https://www.cnblogs.com/chriskwok/archive/2009/12/10/1621279.html

相关文章:

  • C#网络编程之Socket一
  • [笔记].使用Protues仿真Max7129
  • 做一个懂爱的聪明女人
  • 如何创建一个MVC模式的Joomla组件教程(十五) - 创建管理员界面 增加编辑功能 上...
  • 二招搞定IE快捷方式没法打开
  • StatsPack 使用初解
  • ArcGIS中对一组查询结果同时闪烁的实现
  • 鸟哥的基础学习-习题与答案
  • 我的人生谚语
  • 梅德克领导AMD成功转变,明年或将在中国市场持续发力?
  • 基于网络数据采集系统的社交媒体/网络营销
  • SQL创建用户及角色
  • Net设计模式实例之单例模式( Singleton Pattern)
  • vxvm之卷管理
  • mapextreme 2008 的helloworld (1)
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • Angular数据绑定机制
  • Apache Spark Streaming 使用实例
  • centos安装java运行环境jdk+tomcat
  • CSS3 变换
  • Git初体验
  • gops —— Go 程序诊断分析工具
  • JavaScript学习总结——原型
  • Java超时控制的实现
  • Java基本数据类型之Number
  • Laravel 中的一个后期静态绑定
  • maya建模与骨骼动画快速实现人工鱼
  • V4L2视频输入框架概述
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 笨办法学C 练习34:动态数组
  • 机器学习中为什么要做归一化normalization
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 排序算法之--选择排序
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • 微信开放平台全网发布【失败】的几点排查方法
  • 小程序测试方案初探
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • (2)STL算法之元素计数
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (九)信息融合方式简介
  • (篇九)MySQL常用内置函数
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (一)appium-desktop定位元素原理
  • (一)RocketMQ初步认识
  • (一)UDP基本编程步骤
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .NET 8.0 发布到 IIS
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .net core 控制台应用程序读取配置文件app.config
  • .net core 依赖注入的基本用发
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON