Reputation: 1700
When I run the following code with the SELECT at the bottom (Commented out in the code), I get 12 rows. Then I comment out the SELECT and uncomment the UPDATE, and run it. Then go back to SELECT, and there are four rows. 8 got updated and are no longer selected when I use SELECT, but these four persist. Switch back to UPDATE again, and there are still these four rows when I SELECT.
Any ideas?
WITH cte AS (
SELECT r.Request_ID,
rc.Route_id,
rc.Flight_Information_Region,
rc.Route AS rcRoute,
rd.FIR,
rd.Route AS rdRoute
FROM Route_Country rc
INNER JOIN Flight_Legs_Route_Header rh ON (rc.Route_ID = rh.Route_ID)
INNER JOIN Flight_Legs_Route_DETAIL rd ON (rh.Flight_Leg_Route_ID = rd.Flight_Leg_Route_ID AND rc.Flight_Information_Region = rd.FIR)
INNER JOIN Request r ON (rh.Request_ID = r.Request_ID)
WHERE rc.Route <> rd.Route
AND r.Request_Archived = 'N'
)
UPDATE cte SET rdRoute = rcRoute
--SELECT * FROM cte
Upvotes: 0
Views: 86
Reputation: 3266
If an update statement finds more than one record matching the record to be updated, it will update with the value from the first matched record. In your statement, the WHERE rc.Route <> rd.Route
will allow a second set of records to be updated, if other matches exist, since the first updated set is filtered out. A third pass would again update the first set of records since the second update undid the first.
Here is a quick example of how this could happen. Execute this sql over and over again and watch the t1_value
switch back and forth with the same update statement:
-- load test data
if object_id('tempdb..#test1') is null
begin
create table #test1 (id int identity,value int)
insert into #test1 (value) values(1)
end
if object_id('tempdb..#test2') is null
begin
create table #test2 (id int identity,test1_id int,value int)
insert into #test2 (test1_id,value) values(1,1),(1,2)
end
-- update with cte
;with cte as
(
select
t1.id,
t1.value as t1_value,
t2.value as t2_value
from #test1 as t1
inner join #test2 as t2
on t2.test1_id = t1.id
and t2.value <> t1.value
)
update cte set t1_value = t2_value
-- return update cte values
;with cte as
(
select
t1.id,
t1.value as t1_value,
t2.value as t2_value
from #test1 as t1
inner join #test2 as t2
on t2.test1_id = t1.id
and t2.value <> t1.value
)
select * from cte
Upvotes: 1
Reputation: 96552
CTEs are only good for the duration of the one query immediately following thier definition. So what you get is not related in any way to previous runs because the CTE is not persisted.
If you want to update the data, the update the table you want to change the data in not the cte. and then do the select from the CTE to see if any records are still applicable.
If you wnat to do more steps with the CTE data, then use a temp table or table variable instead.
Upvotes: 0