我有一个Sybase表,其结构如下。假设id
列是按时间顺序排列的(最早的一列(。
|id |data|refId|
|---|----|-----|
|1 |d1 |NULL |
|2 |d2 |NULL |
|3 |d3 |NULL |
|4 |d4 |2 |
|5 |d5 |4 |
|6 |d6 |5 |
在存储过程中可以使用哪些SQL代码来产生以下结果:
|id |data|
|---|----|
|1 |d1 |
|2 |d6 |
|3 |d3 |
例如,id 2用新数据修改了3次。首先是第4行,然后是第5行,最后是第6行。
在发布修正案时,我需要始终使用原始id。因此,当我需要在第6行(d6(中发布修改后的数据时,我需要通过使用refId反向链接来找到原始id(2(。
6-->5-->4-->2
由于ids 1&3没有对应的refId,这些行的数据是当前的。
一些额外重要的东西:
Server: Adaptive Server Enterprise/16.0 SP03 PL08
Driver URL: jdbc:jtds:sybase
Driver: Sybase jTDS
假设您的数据在表test
中,下面的sp将在层次结构中循环:
create procedure sp_hierarchical_loop
as
begin
declare @cont int
create table #test2 (
id int,
data char(2),
refId int null
)
insert into #test2
select id, data, id
from test
where refId is null
set @cont = 1
while (@cont>0) begin
update #test2
set t1.data=t2.data, t1.refId=t2.id
from #test2 t1, test t2
where isnull(t1.refId,t1.id)=t2.refId
if (row_count()=0) set @cont=0
end
select id, data
from #test2
end
go
注释有点长。。。
您需要做的第一件事是确定您使用的Sybase RDBMS产品(ASE?IQ?SQL Anywhere?Advantage?(和版本,因为这些产品不共享通用的SQL语法。
如果您使用IQ或SQL Anywhere,则可能会使用使用WITH
或WITH RECURSIVE
子句的公共表表达式(CTE(。关于这个主题的几个链接:博客re:递归查询,博客re:递推并集和沼泽re:递归并集树遍历。
如果你正在使用ASE,那么在CTE方面你就运气不好了(也就是说,ASE不支持这些(。这就需要将过程解决方案(例如,基于游标的循环结构(作为存储过程编写,或者如果运行更新版本的ASE(15.7,16.x(,则可能是用户定义的函数(尽管即使是UDF也需要某种循环/递归编码(。
我不熟悉Advantage,所以除了浏览文档(又名"RTFM"(,看看它是否支持递归CTE或循环/递归编码选项外,我在这里无法提出任何建议。