SqlServer 游标逐行更新数据,根据上一行的数据来更新当前行

/*
drop table #tmpTable

create TABLE #tmpTable(
f_id int IDENTITY(1,1) PRIMARY KEY,--水果id
s_id int not null, --供应商id
f_name varchar(255) not null,--水果名称
f_price decimal(8,2) not null --水果价格
);
insert into #tmpTable (s_id,f_name,f_price)
values
(101,'apple',5.8),
(102,'',6.8),
(105,'orange',4.5),
(102,'banana',3.5),
(103,'',8.0),
(104,'grape',7.6),
(101,'',10.5);


select * from #tmpTable

*/

DECLARE cursor_jxsmb CURSOR FOR --定义一个游标
SELECT f_name,f_price FROM #tmpTable; --定于游标的数据源
OPEN cursor_jxsmb --打开游标

DECLARE @LAST NVARCHAR(4000),@THIS NVARCHAR(4000),@price nvarchar(80) --定义两个变量,用来保存上一行和当前行的数据
FETCH NEXT FROM cursor_jxsmb INTO @THIS,@price --设置@this 为当前行的数据

WHILE @@FETCH_STATUS=0 --判断游标是否为读取失败,读取失败则为-1 代表最后一行
BEGIN
IF LEN(@THIS)<>0 --判断当前读取行字段是否为空
BEGIN
SET @LAST=@price --如果不为空则不更新,并且设置@last为当前行的数据
--PRINT @LAST
END
ELSE
BEGIN --如果为空则更新当前行的数据为上一行
UPDATE #tmpTable SET f_name=@LAST WHERE CURRENT OF cursor_jxsmb --更新数据,where 只更新当前游标所在行
--PRINT @LAST
END

FETCH NEXT FROM cursor_jxsmb INTO @THIS,@price    --继续读取下一行数据

END

CLOSE cursor_jxsmb --关闭游标
DEALLOCATE cursor_jxsmb --释放游标<br>


select * from #tmpTable

 

------------------------------------------------

/*
drop table #tmpTable

create TABLE #tmpTable(
f_id int IDENTITY(1,1) PRIMARY KEY,--水果id
s_id int not null, --供应商id
f_name varchar(255) not null,--水果名称
f_price decimal(8,2) not null --水果价格
);
insert into #tmpTable (s_id,f_name,f_price)
values
(101,'apple',5.8),
(102,'',6.8),
(105,'',4.5),
(102,'',3.5),
(103,'',8.0),
(104,'',7.6),
(101,'',10.5);


select * from #tmpTable

*/

DECLARE cursor_jxsmb CURSOR FOR --定义一个游标
SELECT f_name,f_price FROM #tmpTable; --定于游标的数据源
OPEN cursor_jxsmb --打开游标

DECLARE @LAST NVARCHAR(4000),@THIS NVARCHAR(4000),@price nvarchar(80) --定义两个变量,用来保存上一行和当前行的数据
FETCH NEXT FROM cursor_jxsmb INTO @THIS,@price --设置@this 为当前行的数据

WHILE @@FETCH_STATUS=0 --判断游标是否为读取失败,读取失败则为-1 代表最后一行
BEGIN
IF LEN(@THIS)<>0 --判断当前读取行字段是否为空
BEGIN
SET @LAST=@price --如果不为空则不更新,并且设置@last为当前行的数据
--PRINT @LAST
END
ELSE
BEGIN --如果为空则更新当前行的数据为上一行

UPDATE #tmpTable SET f_name=@LAST WHERE CURRENT OF cursor_jxsmb --更新数据,where 只更新当前游标所在行
--PRINT @LAST
SET @LAST=@price
END

FETCH NEXT FROM cursor_jxsmb INTO @THIS,@price    --继续读取下一行数据

END

CLOSE cursor_jxsmb --关闭游标
DEALLOCATE cursor_jxsmb --释放游标<br>


select * from #tmpTable

-----------------------------------------------

 

--此脚本用于从DIM_VESSEL_REPORTING_EVENT表抽取s数据,和表DIM_VESSEL_REPORTING_BERTH_TO_BERTH_LEG数据对比,如果一致说明DIM_VESSEL_REPORTING_BERTH_TO_BERTH_LEG数据抽取逻辑是正确的


drop table #BERTH_TO_BERTH_LEG
create TABLE #BERTH_TO_BERTH_LEG(
imo int ,
customer_id int ,
leg_model varchar(255) ,
leg_start_date datetime,
leg_end_data datetime
);

select * from #BERTH_TO_BERTH_LEG;

 

declare @IMO int
declare @CUSTOMER_ID int
declare @EVENT varchar(50)
declare @BK_EVENT_DATE datetime
declare @first_date datetime

--declare @leg_start_data datetime
--declare @leg_mode varchar(50)

declare cursor_event cursor scroll

for select BK_VESSEL_IMO,BK_CUSTOMER_ID,EVENT,BK_EVENT_DATE from dbo.DIM_VESSEL_REPORTING_EVENT where BK_VESSEL_IMO = '9336828' and BK_CUSTOMER_ID = '10550971' and SYS_ACTIVE_INDICATOR = 1 order by BK_EVENT_DATE

open cursor_event

while (@@Fetch_Status = 0)

begin
fetch next from cursor_event into @IMO, @CUSTOMER_ID,@EVENT,@BK_EVENT_DATE
if @EVENT='ARRIVAL'
begin
insert into #BERTH_TO_BERTH_LEG (imo,customer_id,leg_model,leg_end_data)values (@IMO, @CUSTOMER_ID,'UnderWay', @BK_EVENT_DATE)
end
else if @EVENT='DEPARTURE'
insert into #BERTH_TO_BERTH_LEG (imo,customer_id,leg_model,leg_end_data)values (@IMO, @CUSTOMER_ID,'InPort', @BK_EVENT_DATE)
end

fetch FIRST from cursor_event into @IMO, @CUSTOMER_ID,@EVENT,@first_date
update top (1) #BERTH_TO_BERTH_LEG set leg_start_date= @first_date
close cursor_event
deallocate cursor_event

 

--select * from #BERTH_TO_BERTH_LEG

--select BK_VESSEL_IMO,BK_CUSTOMER_ID,EVENT,BK_EVENT_DATE from dbo.DIM_VESSEL_REPORTING_EVENT where BK_VESSEL_IMO = '9336828' and BK_CUSTOMER_ID = '10550971' and SYS_ACTIVE_INDICATOR = 1 order by BK_EVENT_DATE


declare @last datetime,@this datetime,@leg_end_data datetime

declare cursor_get_previous_data cursor

for select leg_start_date,leg_end_data from #BERTH_TO_BERTH_LEG
open cursor_get_previous_data
fetch next from cursor_get_previous_data into @this,@leg_end_data
while (@@FETCH_STATUS=0)
BEGIN
IF LEN(@this)<>0
BEGIN
SET @last=@leg_end_data
END

ELSE
BEGIN
UPDATE #BERTH_TO_BERTH_LEG SET leg_start_date=@last WHERE CURRENT OF cursor_get_previous_data
SET @last=@leg_end_data --设置@leg_end_data为当前行的数据
end

FETCH NEXT FROM cursor_get_previous_data INTO @this,@leg_end_data
END

CLOSE cursor_get_previous_data --关闭游标
DEALLOCATE cursor_get_previous_data --释放游标<br>

 


--select * from #BERTH_TO_BERTH_LEG

posted on 2021-12-09 11:16  jenny_200  阅读(460)  评论(0编辑  收藏  举报

导航