2014-04-16 45 views
0

嗨,大家好,我有這樣的問題,關於oracle上的相關更新。ORACLE SQL:相關的更新問題

考慮我有一個表params

id_s id_p value desc 
----------------------------------------------- 
10064  9  aaa  r 
10064  8  bbb  t 
10064  4  ccc  t 
10064  4  ttt  y 
11119  9  ddd  f 
11119  8  eee  g 
11119  4  fff  b 
11119  4  kkk  x 

,所以我想更新PARAMS得到以下

id_s id_p value desc 
----------------------------------------------- 
10064  9  aaa  r 
10064  8  bbb  t 
10064  4  ccc  t 
10064  4  ttt  y 
11119  9  aaa  r 
11119  8  bbb  t 
11119  4  ccc  t 
11119  4  ttt  y 

我寫更新這樣

update params p1 
    set (p1.value, p1.desc) = (
      select p2.value 
       , p2.desc 
      from params p2 
      where p2.id_s = 10064 
       and p2.id_p = p1.id_p 
     ) 
where p1.id_s = 11119 
    ; 

執行返回錯誤「ORA01427:單行子查詢返回更多比一排'

我該如何做到這一點日期工作?

+0

您的查詢應該是罰款 - 你運行帶有'p1.id_p'子查詢一些自己的價值觀所取代? – collapsar

+0

@collapsar是的,我試過了。如果只有一個值而不是p1.id_p,則更新將起作用,但是當p1.id_p有多個值時,則會返回錯誤「ORA01427:單行子查詢返回多行」。 – arminrock

+0

如何確定哪些主記錄和從記錄符合您的快速條件?例如。對於'id_p' = 4你有2! = 2個將id_s' = 10064與id_s' = 11119的記錄相關聯的選項。請注意,如果選擇相關並不重要,則必須確保源和目標集的基數相同。還要注意,這種不變性通常是數據模型破壞的標誌。 – collapsar

回答

0

你有一個附加條件添加到您的子查詢:

update params p1 
    set (p1.value, p1.desc) = (
      select p2.value 
       , p2.desc 
       from params p2 
      where p2.id_s = 10064 
       and p2.id_p = p1.id_p 
       and p1.id_s = 11119 
     ) 
    where p1.id_s = 11119 
     ; 

編輯: 事情是由OP的規格,這實際上相當於部分PK更新的更新更加複雜(據因爲表中摘錄的內容與他們的專欄完全一致)。

一個可能的解決方案實現了以下基本思想:id_pid_s的主組合的結果集根據排序的順序與相同列的從組合的結果集配對。排序僅僅是根據列valuedesc的結果集的順序,但是當然任何其他方式也會這樣做(注意,特別是不同的排列是可行的)。

然後所述配對與更新結果集相關聯。

在Oracle SQL:

update params p1 
    set (p1.value, p1.desc) = (
      select emb.value 
       , emb.desc 
      from (
        select p2.value 
         , p2.desc 
         , p2.id_p 
         , rownum  rn 
         from params p2 
        where p2.id_s = 10064 
        order by p2.value 
         , p2.desc 
       ) emb 
      join (
        select pm.value 
         , pm.desc 
         , pm.id_p 
         , rownum  rn 
         from params pm 
        where pm.id_s = 11119 
        order by pm.value 
         , pm.desc 
       ) emb_master 
         ON ( emb_master.id_p = emb.id_p 
          AND emb_master.rn = emb.rn ) 
      where p1.id_s = 11119 
       and emb_master.id_p  = p1.id_p 
       and emb_master.value = p1.value 
       and emb_master.desc  = p1.desc 
     ) 
where p1.id_s = 11119 
    ; 

該方案的可行性取決於假設結果集模的元組(id_pid_s)相同cardibality的每個值。如果你不這樣做,更新將不完整。

根據給出的摘錄對ora 11g2進行測試。

+0

問題是,我的子查詢返回多個行反正有或沒有你建議的補充我得到ora-01427,我認爲行'和p2.id_p = p1.id_p'應該有所幫助,但它沒有。 – arminrock

+0

您應該再次檢查作爲獨立查詢發佈的子查詢是否生成多於一行。我根據你的問題的表摘錄測試了這個版本對ora 11g2,它按預期工作。 – collapsar

+0

你是對的朋友,我剛剛編輯我的問題糾正了表中的可能值。例如可以有多個id_p的行,具有相同的值 – arminrock

0

當不止一行返回時,您不指定該做什麼。你可以只選擇使用rownum = 1中任意一行:

update params p1 
    set (p1.value, p1.desc) = (
      select p2.value, p2.desc 
      from params p2 
      where p2.id_s = 10064 and p2.id_p = p1.id_p and rownum = 1 
     ) 
where p1.id_s = 11119; 
+0

我剛剛編輯我的問題糾正了表中的可能值。例如對於具有相同值的id_p可以有多行。即時混淆與rownum,這將有助於在這種情況下 – arminrock

+0

@arminrock。 。 。 'rownum = 1'將選擇其中一個匹配行並將其用於更新。這將解決錯誤。我不知道這是你想要的查詢。 –