2011-04-25 21 views
5

我應該翻轉航班號爲雙航班從一組城市來回的,因此,例如:如何交換Oracle SQL中的記錄值?

1439 ATL SFO
1440 SFO ATL

竟又爲:

1440 ATL SFO
1439 SFO ATL

我嘗試這個查詢(因爲你不能更新..加入甲骨文):

UPDATE 
    (SELECT f.airline, f.flightno flightno_f, d.airline, d.flightno flightno_d 
     FROM flights f 
     INNER JOIN flights d ON f.airline = 9 AND 
     f.sourceairport = d.destairport AND 
     f.destairport = d.sourceairport AND d.airline = 9 
     WHERE d.flightno < f.flightno) g 
    SET g.flightno_f = g.flightno_d, 
    g.flightno_d = g.flightno_f; 

航空公司,flightno是航班的主要關鍵。選擇給了我一組正確的,我想交換的記錄,但是UPDATE ... SET給了我這個錯誤:

SET g.flightno_f = g.flightno_d, 
     * 
ERROR at line 7: 
ORA-01779: cannot modify a column which maps to a non key-preserved table 

上我要去哪裏不對任何想法?

+0

@therin嘗試添加約束條件alter table flights add constraint flights_uk unique(flightno); – 2011-04-25 22:40:05

+0

向我創建的視圖添加約束?我不確定你是什麼意思。我嘗試在航班表中添加另一個約束條件,但我一直處理的其他主要問題之一是我無法在航班號上添加唯一約束條件,因此可能會有另一家航空公司的相同航班號。 – therin 2011-04-25 22:42:41

+0

@therin由於您的航班號相同,無法更新 – 2011-04-25 22:46:03

回答

6

爲了更新連接,您選擇的數據集碰巧有效保存密鑰並不重要; Oracle必須能夠從約束和謂詞中看到它將被定義爲密鑰保存。而且,由於您在flightnumber上存在不平等情況,因此數據定義中沒有任何內容可以保證您對給定的源行不會有多個匹配。

如果確保航班號總是相差1,那麼如果將條件更改爲d.flightno + 1 = f.flightno,則可能可以使用連接方法。

在任何情況下,我認爲以下內容將起作用......因爲語句級讀取一致性,即使更新了行,子查詢也應該返回正確的結果。

UPDATE flights f1 
    SET flightno = 
    (SELECT flightno 
     FROM flights f2 
     WHERE f2.airline = f1.airline 
     AND f2.sourceairport = f1.destairport 
     AND f2.destairport = f1.sourceairport 
    ) 
    WHERE airline = 9; 
+0

這很好用,謝謝 – therin 2011-04-26 03:51:58