2015-02-04 4 views
0

Когда я запускаю следующий код с SELECT в нижней части (прокомментировано в коде), я получаю 12 строк. Затем я комментирую SELECT и раскомментирую UPDATE и запускаю его. Затем вернитесь к SELECT, и есть четыре строки. 8 обновлены и больше не выбраны, когда я использую SELECT, но эти четыре сохраняются. Снова вернитесь к UPDATE, и все еще есть эти четыре строки, когда я SELECT.UPDATE обновляет некоторые, но не все строки

Любые идеи?

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 
+0

Do затрагиваемые строки имеют значение NULL в rcRoute? – DBNull

+2

Вы уверены, что это те самые четыре записи, которые вы видите каждый раз? Это обновление могло бы переключать значения двух наборов записей вперед и назад, если для rdRoute соответствует более одного rcRoute. На первом проходе обновляется первое совпадение. На следующем проходе обновляется другой набор, поскольку условие WHERE rc.Route <> rd.Route' отфильтровывает первое совпадение после его обновления. На третьем проходе первое обновление будет повторяться, так как второе обновление отключило первое и т. Д. –

+0

Я изменил запрос и включил rd.Flight_Leg_Route_Detail_ID, который является уникальным идентификатором для строк rd. Они остаются точно такими же рядами. Вот запрос с его данными: http://i.imgur.com/nOcbTj8.jpg –

ответ

1

Если инструкция обновления обнаруживает более одной записи, соответствующей обновляемой записи, она будет обновляться со значением из первой сопоставимой записи. В вашем заявлении WHERE rc.Route <> rd.Route позволит обновить второй набор записей, если существуют другие соответствия, поскольку первый обновленный набор отфильтровывается. Третий проход снова обновит первый набор записей, поскольку второе обновление отключилось первым.

Вот краткий пример того, как это может произойти. Выполнить этот SQL снова и снова, и смотреть переключатель t1_value назад и вперед с той же инструкции обновления:

-- 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 
+0

Я изменил запрос и включил rd.Flight_Leg_Route_Detail_ID, который является уникальным идентификатором для строк rd. Они остаются точно такими же рядами. Вот запрос с его данными: http://i.imgur.com/nOcbTj8.jpg Надеюсь, что поможет уточнить. –

+0

Я удалил условие «где rc.Route <> rd.Route» (по существу обновляя все строки, где request_archive = 'N'. Он обновил 563 строки, и все же эти 4 строки снова остаются. Идентификаторы одинаковых строк. –

+1

Ron Смит прав.На вашем снимке экрана у вас есть две пары записей, которые просто переключают значения rdRoute взад и вперед каждый раз, когда вы запускаете обновление. Вам нужно уточнить свой запрос, чтобы устранить двусмысленность. – DBNull

0

CTEs хороши только в течение одного запроса сразу после определения. Так что вы получаете никак не связано с предыдущими запусками, потому что CTE не сохраняется.

Если вы хотите обновить данные, обновите таблицу, в которой вы хотите изменить данные, а не cte. а затем сделайте выбор из CTE, чтобы узнать, все ли применимы записи.

Если вы хотите сделать больше шагов с данными CTE, используйте вместо этого таблицу temp или таблицу.

Смежные вопросы