2015-12-02 127 views
0

我在更新某些记录时遇到了错误,并且需要一些帮助来“恢复”它们。我需要下面的数据,我需要EC和INVOICE_NUM KEYWORD有一个迭代器后缀,就像下面所示的期望结果一样。Oracle使用迭代器更新数据

如何遍历我的所有记录,并针对EC和INVOICE_NUM KEYWORD具有> 1 VALUE的每个RID执行此操作?如果只有一个EC或INVOICE_NUM,则不需要更新,它可以保留为EC或INVOICE_NUM。

在制作:

RID  KEYWORD  VALUE 
692307 BANK_NUM  17       
692307 CHECK_AMT  $ 2504.62     
692307 CHECK_DT  71121     
692307 CHECK_NUM  27034      
692307 DOC_NAME  Expense-Check    
692307 EC    71103CTRC    
692307 EC    71027TNRF    
692307 EC    71114TXWCS    
692307 EC    71117TXCP    
692307 EC    7111ONJAD    
692307 FILENAME  Q:\teleform\00028076\0  
692307 INVOICE_NUM 2193000086     
692307 INVOICE_NUM 9190000875     
692307 INVOICE_NUM 9600010418     
692307 INVOICE_NUM 9600010414     
692307 INVOICE_NUM 8100000372     
692307 VEND_NAME  KINKO'S INC.    
692307 VEND_NUM  1002838      

期望的结果:

RID  KEYWORD  VALUE 
692307 BANK_NUM  17      
692307 CHECK_AMT  $ 2504.62    
692307 CHECK_DT  71121    
692307 CHECK_NUM  27034     
692307 DOC_NAME  Expense-Check   
692307 EC_1   71103CTRC   
692307 EC_2   71027TNRF   
692307 EC_3   71114TXWCS   
692307 EC_4   71117TXCP   
692307 EC_5   7111ONJAD   
692307 FILENAME  Q:\teleform\00028076\0 
692307 INVOICE_NUM_1 9190000875    
692307 INVOICE_NUM_2 2193000086    
692307 INVOICE_NUM_3 9600010418    
692307 INVOICE_NUM_4 9600010414    
692307 INVOICE_NUM_5 8100000372    
692307 VEND_NAME  KINKO'S INC.   
692307 VEND_NUM  1002838    

同上的查询结果:

RID   ORIGINAL_KEYWORD VALUE   NEW_KEYWORD 
3361978 DOC_NAME    Expense-Check DOC_NAME_1 
3361979 DOC_NAME    Expense-Check DOC_NAME_2 
3361980 DOC_NAME    Expense-Check DOC_NAME_3 
3361981 DOC_NAME    Expense-Check DOC_NAME_4 
3361982 DOC_NAME    Expense-Check DOC_NAME_5 
3361983 DOC_NAME    Expense-Check DOC_NAME_6 
3361984 DOC_NAME    Expense-Check DOC_NAME_7 
3361985 DOC_NAME    Expense-Check DOC_NAME_8 
3361986 DOC_NAME    Expense-Check DOC_NAME_9 
3361987 DOC_NAME    Expense-Check DOC_NAME_10 

*更多更新*

RID  KEYWORD   VALUE 
5716220 BANK_NUMBER  17      
5716220 CHECK_AMOUNT  $ 3797.68    
5716220 CHECK_DATE  141211     
5716220 CHECK_NUMBER  67714     
5716220 DOC_NAME   Expense-Check   
5716220 EVENT_CODE  141107NVCC    
5716220 EVENT_CODE  141107NVCC    
5716220 EVENT_CODE  141113FLRC    
5716220 EVENT_CODE  141031INRA    
5716220 EVENT_CODE  141107MSAM    
5716220 EVENT_CODE  141113SCRCO   
5716220 FILENAME   Q:\teleform\00133619\0 
5716220 INVOICE_NUMBER DB791094    
5716220 INVOICE_NUMBER 791094     
5716220 INVOICE_NUMBER 792456     
5716220 INVOICE_NUMBER 789983     
5716220 INVOICE_NUMBER 791910     
5716220 INVOICE_NUMBER 792452     
5716220 VENDOR_NAME  VTECH     
5716220 VENDOR_NUMBER 1001685    

5716221 BANK_NUMBER  17      
5716221 CHECK_AMOUNT  $ 3797.68    
5716221 CHECK_DATE  141211     
5716221 CHECK_NUMBER  67714     
5716221 DOC_NAME   Expense-Check   
5716221 EVENT_CODE  141113SCRCO   
5716221 EVENT_CODE  141113AZRAR   
5716221 EVENT_CODE  141104MORER   
5716221 FILENAME   Q:\teleform\00133619\1 
5716221 INVOICE_NUMBER 792959     
5716221 INVOICE_NUMBER 792508     
5716221 INVOICE_NUMBER 790437     
5716221 VENDOR_NAME  VTECH     
5716221 VENDOR_NUMBER 1001685    

5716222 BANK_NUMBER  17      
5716222 CHECK_AMOUNT  $ 7782.73    
5716222 CHECK_DATE  141211     
5716222 CHECK_NUMBER  67711     
5716222 DOC_NAME   Expense-Check   
5716222 EVENT_CODE        
5716222 EVENT_CODE        
5716222 FILENAME   Q:\teleform\00133616\0 
5716222 INVOICE_NUMBER 150562     
5716222 INVOICE_NUMBER 150533     
5716222 VENDOR_NAME  TGRAPH 
5716222 VENDOR_NUMBER 1001672    

结果应该是这样的:

RID  KEYWORD   VALUE 
5716220 BANK_NUMBER  17      
5716220 CHECK_AMOUNT  $ 3797.68    
5716220 CHECK_DATE  141211     
5716220 CHECK_NUMBER  67714     
5716220 DOC_NAME   Expense-Check   
5716220 EVENT_CODE_1  141107NVCC    
5716220 EVENT_CODE_2  141107NVCC    
5716220 EVENT_CODE_3  141113FLRC    
5716220 EVENT_CODE_4  141031INRA    
5716220 EVENT_CODE_5  141107MSAM    
5716220 EVENT_CODE_6  141113SCRCO   
5716220 FILENAME   Q:\teleform\00133619\0 
5716220 INVOICE_NUMBER_1 DB791094    
5716220 INVOICE_NUMBER_2 791094     
5716220 INVOICE_NUMBER_3 792456     
5716220 INVOICE_NUMBER_4 789983     
5716220 INVOICE_NUMBER_5 791910     
5716220 INVOICE_NUMBER_6 792452     
5716220 VENDOR_NAME  VTECH     
5716220 VENDOR_NUMBER 1001685    

5716221 BANK_NUMBER  17      
5716221 CHECK_AMOUNT  $ 3797.68    
5716221 CHECK_DATE  141211     
5716221 CHECK_NUMBER  67714     
5716221 DOC_NAME   Expense-Check   
5716221 EVENT_CODE_1  141113SCRCO   
5716221 EVENT_CODE_2  141113AZRAR   
5716221 EVENT_CODE_3  141104MORER   
5716221 FILENAME   Q:\teleform\00133619\1 
5716221 INVOICE_NUMBER_1 792959     
5716221 INVOICE_NUMBER_2 792508     
5716221 INVOICE_NUMBER_3 790437     
5716221 VENDOR_NAME  VTECH     
5716221 VENDOR_NUMBER 1001685    

5716222 BANK_NUMBER  17      
5716222 CHECK_AMOUNT  $ 7782.73    
5716222 CHECK_DATE  141211     
5716222 CHECK_NUMBER  67711     
5716222 DOC_NAME   Expense-Check   
5716222 EVENT_CODE_1        
5716222 EVENT_CODE_2        
5716222 FILENAME   Q:\teleform\00133616\0 
5716222 INVOICE_NUMBER_1 150562     
5716222 INVOICE_NUMBER_2 150533     
5716222 VENDOR_NAME  TGRAPH 
5716222 VENDOR_NUMBER 1001672    

表的结构如上所示。数据来自需要更新的同一张表。

+0

那你试试? – Iffo

+0

排序他们的标准是什么?例如,为什么“EC_1 71103CTRC”和“EC_2 71027TNRF”,而不是“EC_2 71103CTRC”和“EC_1 71027TNRF”? – Ditto

+0

@同上,没关系,没关系。 – MB34

回答

1

尝试是这样的:

with w_data as (
     select 5716220 rid, rtrim('BANK_NUMBER ') keyword, rtrim('17     ') value from dual union all 
     select 5716220 rid, rtrim('CHECK_AMOUNT ') keyword, rtrim('$ 3797.68    ') value from dual union all 
     select 5716220 rid, rtrim('CHECK_DATE ') keyword, rtrim('141211    ') value from dual union all 
     select 5716220 rid, rtrim('CHECK_NUMBER ') keyword, rtrim('67714     ') value from dual union all 
     select 5716220 rid, rtrim('DOC_NAME  ') keyword, rtrim('Expense-Check   ') value from dual union all 
     select 5716220 rid, rtrim('EVENT_CODE ') keyword, rtrim('141107NVCC   ') value from dual union all 
     select 5716220 rid, rtrim('EVENT_CODE ') keyword, rtrim('141107NVCC   ') value from dual union all 
     select 5716220 rid, rtrim('EVENT_CODE ') keyword, rtrim('141113FLRC   ') value from dual union all 
     select 5716220 rid, rtrim('EVENT_CODE ') keyword, rtrim('141031INRA   ') value from dual union all 
     select 5716220 rid, rtrim('EVENT_CODE ') keyword, rtrim('141107MSAM   ') value from dual union all 
     select 5716220 rid, rtrim('EVENT_CODE ') keyword, rtrim('141113SCRCO   ') value from dual union all 
     select 5716220 rid, rtrim('FILENAME  ') keyword, rtrim('Q:\teleform\00133619\0') value from dual union all 
     select 5716220 rid, rtrim('INVOICE_NUMBER') keyword, rtrim('DB791094    ') value from dual union all 
     select 5716220 rid, rtrim('INVOICE_NUMBER') keyword, rtrim('791094    ') value from dual union all 
     select 5716220 rid, rtrim('INVOICE_NUMBER') keyword, rtrim('792456    ') value from dual union all 
     select 5716220 rid, rtrim('INVOICE_NUMBER') keyword, rtrim('789983    ') value from dual union all 
     select 5716220 rid, rtrim('INVOICE_NUMBER') keyword, rtrim('791910    ') value from dual union all 
     select 5716220 rid, rtrim('INVOICE_NUMBER') keyword, rtrim('792452    ') value from dual union all 
     select 5716220 rid, rtrim('VENDOR_NAME ') keyword, rtrim('VTECH     ') value from dual union all 
     select 5716220 rid, rtrim('VENDOR_NUMBER ') keyword, rtrim('1001685    ') value from dual union all 
     select 5716221 rid, rtrim('BANK_NUMBER ') keyword, rtrim('17     ') value from dual union all 
     select 5716221 rid, rtrim('CHECK_AMOUNT ') keyword, rtrim('$ 3797.68    ') value from dual union all 
     select 5716221 rid, rtrim('CHECK_DATE ') keyword, rtrim('141211    ') value from dual union all 
     select 5716221 rid, rtrim('CHECK_NUMBER ') keyword, rtrim('67714     ') value from dual union all 
     select 5716221 rid, rtrim('DOC_NAME  ') keyword, rtrim('Expense-Check   ') value from dual union all 
     select 5716221 rid, rtrim('EVENT_CODE ') keyword, rtrim('141113SCRCO   ') value from dual union all 
     select 5716221 rid, rtrim('EVENT_CODE ') keyword, rtrim('141113AZRAR   ') value from dual union all 
     select 5716221 rid, rtrim('EVENT_CODE ') keyword, rtrim('141104MORER   ') value from dual union all 
     select 5716221 rid, rtrim('FILENAME  ') keyword, rtrim('Q:\teleform\00133619\1') value from dual union all 
     select 5716221 rid, rtrim('INVOICE_NUMBER') keyword, rtrim('792959    ') value from dual union all 
     select 5716221 rid, rtrim('INVOICE_NUMBER') keyword, rtrim('792508    ') value from dual union all 
     select 5716221 rid, rtrim('INVOICE_NUMBER') keyword, rtrim('790437    ') value from dual union all 
     select 5716221 rid, rtrim('VENDOR_NAME ') keyword, rtrim('VTECH     ') value from dual union all 
     select 5716221 rid, rtrim('VENDOR_NUMBER ') keyword, rtrim('1001685    ') value from dual union all 
     select 5716222 rid, rtrim('BANK_NUMBER ') keyword, rtrim('17     ') value from dual union all 
     select 5716222 rid, rtrim('CHECK_AMOUNT ') keyword, rtrim('$ 7782.73    ') value from dual union all 
     select 5716222 rid, rtrim('CHECK_DATE ') keyword, rtrim('141211    ') value from dual union all 
     select 5716222 rid, rtrim('CHECK_NUMBER ') keyword, rtrim('67711     ') value from dual union all 
     select 5716222 rid, rtrim('DOC_NAME  ') keyword, rtrim('Expense-Check   ') value from dual union all 
     select 5716222 rid, rtrim('EVENT_CODE ') keyword, rtrim('      ') value from dual union all 
     select 5716222 rid, rtrim('EVENT_CODE ') keyword, rtrim('      ') value from dual union all 
     select 5716222 rid, rtrim('FILENAME  ') keyword, rtrim('Q:\teleform\00133616\0') value from dual union all 
     select 5716222 rid, rtrim('INVOICE_NUMBER') keyword, rtrim('150562    ') value from dual union all 
     select 5716222 rid, rtrim('INVOICE_NUMBER') keyword, rtrim('150533    ') value from dual union all 
     select 5716222 rid, rtrim('VENDOR_NAME ') keyword, rtrim('TGRAPH    ') value from dual union all 
     select 5716222 rid, rtrim('VENDOR_NUMBER ') keyword, rtrim('1001672    ') value from dual 
    ) 
select rid, 
     CASE WHEN keyword in ('EVENT_CODE', 'INVOICE_NUMBER') 
      THEN 
       keyword || '_' || row_number() over (partition by rid, keyword order by value) 
      ELSE 
       keyword 
     END keyword, 
     value 
    from (select rid, keyword, value, 
       count(*) over (partition by rid, keyword) rcount 
      from w_data 
     ) 
/

     RID KEYWORD      VALUE 
    ---------- ------------------------------ ---------------------- 
    5716220 BANK_NUMBER     17 
    5716220 CHECK_AMOUNT     $ 3797.68 
    5716220 CHECK_DATE      141211 
    5716220 CHECK_NUMBER     67714 
    5716220 DOC_NAME      Expense-Check 
    5716220 EVENT_CODE_1     141031INRA 
    5716220 EVENT_CODE_2     141107MSAM 
    5716220 EVENT_CODE_3     141107NVCC 
    5716220 EVENT_CODE_4     141107NVCC 
    5716220 EVENT_CODE_5     141113FLRC 
    5716220 EVENT_CODE_6     141113SCRCO 
    5716220 FILENAME      Q:\teleform\00133619\0 
    5716220 INVOICE_NUMBER_1    789983 
    5716220 INVOICE_NUMBER_2    791094 
    5716220 INVOICE_NUMBER_3    791910 
    5716220 INVOICE_NUMBER_4    792452 
    5716220 INVOICE_NUMBER_5    792456 
    5716220 INVOICE_NUMBER_6    DB791094 
    5716220 VENDOR_NAME     VTECH 
    5716220 VENDOR_NUMBER     1001685 
    5716221 BANK_NUMBER     17 
    5716221 CHECK_AMOUNT     $ 3797.68 
    5716221 CHECK_DATE      141211 
    5716221 CHECK_NUMBER     67714 
    5716221 DOC_NAME      Expense-Check 
    5716221 EVENT_CODE_1     141104MORER 
    5716221 EVENT_CODE_2     141113AZRAR 
    5716221 EVENT_CODE_3     141113SCRCO 
    5716221 FILENAME      Q:\teleform\00133619\1 
    5716221 INVOICE_NUMBER_1    790437 
    5716221 INVOICE_NUMBER_2    792508 
    5716221 INVOICE_NUMBER_3    792959 
    5716221 VENDOR_NAME     VTECH 
    5716221 VENDOR_NUMBER     1001685 
    5716222 BANK_NUMBER     17 
    5716222 CHECK_AMOUNT     $ 7782.73 
    5716222 CHECK_DATE      141211 
    5716222 CHECK_NUMBER     67711 
    5716222 DOC_NAME      Expense-Check 
    5716222 EVENT_CODE_1 
    5716222 EVENT_CODE_2 
    5716222 FILENAME      Q:\teleform\00133616\0 
    5716222 INVOICE_NUMBER_1    150533 
    5716222 INVOICE_NUMBER_2    150562 
    5716222 VENDOR_NAME     TGRAPH 
    5716222 VENDOR_NUMBER     1001672 

    46 rows selected. 

[编辑]基于以下评析更新。并更好地匹配预期的结果[/编辑]

WITH子句只是创建你的数据......你可以把它从“w_data”改为你的表。

内部查询只是抓取数据并计算每个“组”中不同关键字的发生次数。

外部查询使用CASE仅在计数器上添加EVENT_CODE和INVOICE_NUMBER。 那里的新列使用每个组的row_number并将它切片在一起。

你可以把那个查询返回到一个MERGE语句,最简单的方法来更新:

MERGE INTO <yourtable> base 
    USING (<query above> 
      ) new 
     ON (new.rid = base.rid 
      and new.value = base.value 
      and new.original_keyword = base.keyword) 
    WHEN MATCHED THEN UPDATE 
     SET base.keyword = new.keyword 
/
+0

该查询会为每个关键字添加分子。 – MB34

+0

@ MB34 ??不,它不,WHERE子句“rcount> 1”可以防止... – Ditto

+0

获取'在ON子句中引用的列无法更新:“BASE”。“KEYWORD”' – MB34

1

希望下面的人帮助:

declare 
INCR NUMBER:=1; 
INCR1 NUMBER:=1; 
CNT_EC NUMBER; 
CNT_INV NUMBER; 
begin 
SELECT COUNT(KEYWORD) INTO CNT_EC FROM TABLE WHERE KEYWORD='EC'; 
SELECT COUNT(KEYWORD) INTO CNT_INV FROM TABLE WHERE KEYWORD='INVOICE_NUM'; 
IF CNT_EC>1THEN 
FOR I IN(SELECT rid,keyword,value from table where rid>1 and keyword='EC') LOOP 
UPDATE TABLE SET KEYWORD=I.KEYWORD||'_'||INCR AND KEYWORD=I.KEYWORD AND VALUE=I.VALUE and rid=i.rid; 
INCR:=INCR+1; 
END LOOP; 
END IF; 
IF CNT_INV>1 THEN 
FOR J IN(SELECT rid,keyword,value from table where rid>1 and keyword='INVOICE_NUM') LOOP 
UPDATE TABLE SET KEYWORD=J.KEYWORD||'_'||INCR1 AND KEYWORD=J.KEYWORD AND VALUE=J.VALUE and rid=j.rid; 
INCR:=INCR1+1; 
END LOOP; 
END IF; 
END; 

**

+0

这工作'有点'。代码中有一个错误,它将每个EC关键字和每个INVOICE_NUM关键字设置为相同的RID。 – MB34

+0

@Preethi:基本经验法则:尽量避免使用PL/SQL,如果您可以在SQL中完成;) – Ditto