2009-06-16 72 views
1

有没有办法轻松/优雅地更新表中的多个列,并使用Oracle 10g中的查询的记录值?Oracle 10g PL/SQL-选择结果作为更新列值

我有一个表(称为源),它有简单起见,2列,IDKEY

 
trunc(ID/100) key1 key2 key3 key4 ..... key99 
------------- ---- ---- ---- ---- 
0    1000 1000 5000 1000 
1    8000 9000 7000 9000 
2     5  5    

的ID是:

 
ID  Key 
---- ---- 
1  1000 
2  1000 
3  5000 
4  1000 
.. 
101  8000 
102  9000 
103  7000 
104  9000 
... 
201   5 
202   5 
... 

我还有一个表需要trunc(ID/100)并使用它作为一个batchID 与列是为在该批次中的ID键映射(称之为KeyMap)创建并批量处理,所以在批处理结束时,我想调用存储过程来更新KeyMap表中的记录,并使用新的Key值更新1个更新语句中的记录,并使用子选择或集合来提供那些关键值。

这是可能的,什么是最好/最有效的方法呢?

+0

我对你的问题有不好的预感。看起来你正在寻找一种优雅的方式去做一些毫无意义的事情......但也许这只是你的例子被过分简化了。 – 2009-06-16 19:08:20

回答

8

我会限制我的批评,说你的餐桌设计不规范,并不是很漂亮,但我会假设你有你的理由。我通常使用DECODE与聚合列结合的方式进行这些“旋转”查询,按照我的密钥进行分组 - 在本例中为您的伪密钥trunc(ID/100)。再加上使用的元组的更新语法:

UPDATE Foo 
    SET (a, b, c, d) 
     = (w, x, y, z); 

,你会得到:

UPDATE KeyMap 
    SET 
     (key1 
     , key2 
     , key3 
     , key4 
     ... 
     , key99 
     ) 
     = (SELECT MAX(decode(mod(ID, 100), 1, Key, NULL)) 
       , MAX(decode(mod(ID, 100), 2, Key, NULL)) 
       , MAX(decode(mod(ID, 100), 3, Key, NULL)) 
       , MAX(decode(mod(ID, 100), 4, Key, NULL)) 
       ... 
       , MAX(decode(mod(ID, 100), 99, Key, NULL)) 
      FROM Source 
      WHERE Trunc(Source.ID/100) = KeyMap.batchId 
      GROUP BY Trunc(Source.ID/100) 
     ) 
    WHERE BatchId = <x>; 
0

您可以生成一个Oracle VARRAY并批量传递您的密钥。你的过程可以迭代VARRAY并更新表。