一问一答:存储过程经典问题

存储过程|问题

只涉及到一个表:xkb_treeNode

表结构是这样:
node_id          int      //节点id
parentNode_id    int      //父节点id
node_text        varchar  //节点内容
isModule         bit      //是否叶子节点

现在保存的数据有:

node_id  parentNode_id  node_text        isModule
   1        -1          语言与文学           0
   2        -1            数学               0
   3        -1            技术               0
   4         1            语文               0
   5         1            外语               0
   6         5            英语               0
   7         6          初中英语             0
   8         7           特斯塔              1
   9         4           测定是2             1
   10        2            测试3              1

现在问题是:
能否通过做一个存储过程,
根据表中的isModule字段的取值(取值为1的表示最终叶子结点),
比如“特斯塔”为叶子节点,层层向上递进找到”特斯塔“的祖先节点:
特斯塔-〉初中英语-〉英语-〉外语-〉语言与文学
即通过”特斯塔“找到”语言与文学“来

最终返回的形态为:
叶子节点id  父节点id      节点名称      祖先节点名称  祖先节点id
   8           7           特斯塔        语言与文学       1
   9           4           测定是2       语言与文学       1
   10          2           测试3           数学           2

 

/////////////////////////////////////////////////////////////////////////
正确答案:

 --生成测试数据
create table xkb_treeNode(
node_id        int,
parentNode_id   int,
node_textvarchar(10),
isModulebit)

insert into xkb_treeNode select 1  ,-1,'语言与文学',0
insert into xkb_treeNode select 2  ,-1,'数学',0
insert into xkb_treeNode select 3  ,-1,'技术',0
insert into xkb_treeNode select 4  , 1,'语文',0
insert into xkb_treeNode select 5  , 1,'外语',0
insert into xkb_treeNode select 6  , 5,'英语',0
insert into xkb_treeNode select 7  , 6,'初中英语',0
insert into xkb_treeNode select 8  , 7,'特斯塔'        ,1
insert into xkb_treeNode select 9  , 4,'测定是2',1
insert into xkb_treeNode select 10 , 2,'测试3',1

--创建存储过程
create procedure sp_test
as
begin
   select
       a.node_id,
       a.parentNode_id,
       a.node_text,
       b.node_id   as ancestor_id  ,
       b.node_text as ancestor_text     
   into
       #t
   from
       xkb_treeNode a,xkb_treeNode b
   where
       a.parentNode_id = b.node_id and a.isModule = 1 
  
   while(exists(select 1 from xkb_treeNode a,#t b where a.node_id=ancestor_id and a.parentNode_id != -1))
   begin
       update #t
       set
           ancestor_id   = b.p_id,
           ancestor_text = b.p_text
       from
           #t a,
           (select
               c.node_id,
               d.node_id as p_id,
               d.node_text as p_text
            from
               xkb_treeNode c,xkb_treeNode d
            where
               c.parentNode_id = d.node_id) b
       where
           a.ancestor_id = b.node_id
   end
  
   select * from #t order by node_id
end

--执行存储过程,结果楼主自己看
exec sp_test

时间: 2024-11-08 18:17:24

一问一答:存储过程经典问题的相关文章

《Visual C# 2010入门经典》一1.6 问与答

1.6 问与答 Visual C# 2010入门经典问:.NET Framework是什么? 答:.NET Framework是一个平台,让开发人员能够以独立于语言和平台的方式创建并运行下一代应用程序和Web服务,还有助于消除(起码是减少)众多常见的编程错误. 问:公共语言运行时(CLR)是什么? 答:公共语言运行时(CLR)是.NET Framework的核心,而C#运行在.NET Framework之上. 问:托管应用程序和非托管应用程序之间有何不同? 答:针对.NET Framework编

《Android应用开发入门经典(第3版)》——第1.7节问与答

1.7 问与答 Android应用开发入门经典(第3版) 问题:使用ADT包是否是入门的最佳方式? 答案:ADT包是开始进行Android开发的最快和最简单的方式,但读者如果已经有了一个Eclipse实例或者使用的IDE不是Eclipse,那么就需要分别安装Android SDK.平台以及平台工具并继续使用自己熟悉的开发环境. 问题:是否应该使用可视化工具来创建用户界面? 答案:尽管本章仅对这个工具做了一个介绍,但一般来讲需要这样做.随着对Android布局的深入了解,读者可能会发现自己既会使用

《Node.js入门经典》一2.10 问与答

2.10 问与答 Node.js入门经典 问:我刚刚开始学习使用Node.js,我应当使用模块吗? 答:是的.通过使用模块可以快速地给应用程序加入许多功能.模块通常可以为开发人员除去常见的困难.比如,Express模块让使用Node.js进行Web开发变得简单. 问:有许多模块可以解决我的问题,哪个模块最好? 答:你应当使用社区中最为流行的模块.可以通过使用位于http://blago.dachev.com/modules和http://eirikb.github.com/nipster/的搜索

《Node.js入门经典》一1.5 问与答

1.5 问与答 Node.js入门经典 问:我能在服务器上使用JavaScript吗?JavaScript不是只能在浏览器上用吗? 答:JavaScript绝对可以用在服务器上,而且,它的许多特性使其精于此道.编写服务器端的JavaScript有许多好处,尤其在需要处理并发的时候.如果读者有使用诸如jQuery这样的框架编写JavaScript的经验,就会在Node.js中看到相似的模式. 问:创建Web应用程序,Node.js比PHP.Python..NET或Ruby好吗? 答:要评估哪个编程

《jQuery Mobile入门经典》—— 2.5 问与答

2.5 问与答 jQuery Mobile入门经典问:单行层级格式的样式表会造成任何渲染上的问题吗?答:是的,使用单行层级格式的样式表对某些浏览器来说可能偶尔会造成问题.当在CSS中设置属性和值的时候,如果忘记在某个值前面添加一个空格,这个值可能会被跳过,导致样式不完整.这就是为什么许多开发者更喜欢使用段落样式,并且在生产机上使用之前再压缩代码的另一个原因. 问:即使开发者们现在使用CSS来表现样式,我可以仍然使用表格吗?答:当然可以.只是要记住,只有为了显示列表数据才使用表格.真的应该避免作为

《jQuery Mobile入门经典》—— 1.5 问与答

1.5 问与答 jQuery Mobile入门经典问:对移动开发来说,Web服务器是必不可少的吗?答:这是一个很好的问题,但回答起来有点难.如果您的移动网站是静态的,不使用任何动态的代码,那么您可以不使用服务器来开发.不过,除非开发的是一个单页的网站,要不然当您尝试载入各个单独的页面的时候,可能会遇到错误信息.使用服务器可以有更好的效果,可以使用AJAX,还可以使用模拟器或者处于相同网络的真机来测试网站在不同设备上的情况. 问:我必须使用IDE来进行开发吗?推荐的IDE太贵了,或者对我来说没有吸

《HTML5移动应用开发入门经典》—— 1.8 问与答

1.8 问与答 HTML5移动应用开发入门经典问:我并不熟悉HTML,因此害怕在开发HTML5应用程序过程中会遇到困难.那么我是否需要在学习HTML5之前了解HTML4? 答:尽管学习HTML 4会打下更好的基础,但HTML5的学习并不困难.虽然本书大部分内容都与HTML5相关,但通过复制例子中的源代码以及阅览本书配套网站的源文件,就可以理解HTML5. 问:我已经拥有一个网站,现在想让移动用户也能够使用它.请问我如何确认是否提供了移动用户需要的功能? 答:最好的做法是直接咨询用户的意见.可以通

《HTML5移动应用开发入门经典》—— 2.8 问与答

2.8 问与答 HTML5移动应用开发入门经典问:在哪里可以了解到更多的HTML5标签及属性? 答:本书稍后将介绍更多新标签及属性.当然你可以访问W3C官网www.w3.org/来了解最新的消息. 问:我准备使用HTML5标签编写Web页面了,但如果浏览器不支持HTML5,怎样确认我写的标签是正确的呢? 答:Web浏览器支持是大部分Web开发者遭遇的难题.HTML5并没有解决这个难题,但还是可以使用W3C官网上的HTML5一致性验证器,以及位于http://html5.validator.nu/

《C++入门经典(第5版•修订版)》——2.6 问与答

2.6 问与答 C++入门经典(第5版•修订版)问:在C++程序中,字符#有何用途? 答: #符号指出当前代码行是一个编译指令:需要在程序编译器处理的命令.编译指令#include将指定文件的所有内容插入到当前位置.编译器看不到编译指令,相反,结果就像是在指定位置输入了文件的全部内容一样. 问:注释类型//和/*有何不同? 答:以//打头的注释是单行注释,到当前行行尾结束.以/打头的注释是多行注释,到下一个/处才结束.函数结束不会导致多行注释结束,只有添加了*/标志多行注释结束,否则编译器将报错

《C++入门经典(第5版•修订版)》——6.7 问与答

6.7 问与答 C++入门经典(第5版•修订版)问:如何在if-else和switch之间做出选择? 答:如果多个else子句测试同一个表达式,就应考虑改用switch语句:如果需要进行比较测试,如a>b,则不能使用switch语句. 问:如何在while和do-while做出选择? 答:如果循环体至少需要执行一次,应考虑使用do-while循环:否则,尽可能使用while循环. 问:如何在while和for之间做出选择? 答:如果要初始化计数变量,且每次循环迭代都检查并递增该变量,应考虑使用f