【发布时间】:2020-01-13 16:58:11
【问题描述】:
如何避免使用游标来实现以下内容?我读到它可以用 CTE 完成,但我没有得到相同的结果。
在示例中,我使用了两个表,第一个是 holder 表,其中包含人员列表,以及 transfer 表,其中每次转移都指示第一个表的特定记录的更改。
您可以在下面看到代码,它带来了正确的结果:
create table #holders(Person VARCHAR(50), Kind VARCHAR(50), Pctg FLOAT)
create table #transfers(Person_FROM VARCHAR(50), Person_To VARCHAR(50), Kind VARCHAR(50), Pctg_New FLOAT, Eff_Date DATE)
insert into #holders
select 'Person One', 'Kind 1', 50 union all
select 'Person Two', 'Kind 1', 50 union all
select 'Person Three', 'Kind 1', NULL union all
select 'Person Four', 'Kind 1', NULL union all
select 'Person One', 'Kind 2', 100
insert into #transfers
select 'Person One', 'Person A', 'Kind 1', 70, '2019-12-31' union all
select 'Person Two', 'Person B', 'Kind 1', 30, '2020-01-01' union all
select 'Person A', 'Person A1', 'Kind 1', 70, '2020-01-02' union all
select 'Person A', 'Person A2', 'Kind 1', 70, '2020-01-03' union all --Should Avoided
select 'Person A2', 'Person A3', 'Kind 1', 70, '2020-01-04' union all --Should Avoided
select 'Person A1', 'Person A4', 'Kind 1', 70, '2020-01-05'
declare
@Person_FROM varchar(50),
@Person_To varchar(50),
@Kind varchar(50),
@Pctg_New float
declare cur cursor for select Person_FROM, Person_To, Kind, Pctg_New from #transfers order by Eff_Date
open cur
fetch next from cur into @Person_FROM, @Person_To, @Kind, @Pctg_New
while @@FETCH_STATUS = 0 begin
update #holders set Person = @Person_To, Pctg = @Pctg_New where Person = @Person_FROM AND Kind = @Kind
fetch next from cur into @Person_FROM, @Person_To, @Kind, @Pctg_New
end
close cur
deallocate cur
SELECT * FROM #holders
drop table #holders
drop table #transfers
(正确的)结果如下:
【问题讨论】:
-
这只是为了学习吗?我只问了一个非常相似的问题:stackoverflow.com/questions/46153033/…
-
嗨列奥尼达,感谢您的评论。我认为实际上并非如此,因为这里需要对更新进行序列化(例如:“Person One”->“Person A”->“Person A1”->“Person A1”->“人 A4")
标签: sql-server serialization sql-update cursor common-table-expression