简体   繁体   English

在Oracle 9i中仅与“匹配后更新”合并

[英]Merge with only 'when matched then update' In Oracle 9i

I am working at a company with Oracle 9i 9.2, and I am unable to upgrade. 我正在使用Oracle 9i 9.2的公司工作,无法升级。

A merge which only does an update on matched, not an insert on not-matched, seems not to work in this version. 在此版本中,仅对匹配项进行更新而不对不匹配项进行插入的合并似乎不适用于此版本。

I am trying to do: 我正在尝试做:

MERGE INTO CDLREFWORK.pricing d --table to insert to 
   USING    V_REC  S  --table source 
   ON ( D.item_id = S.item_id
        and   d.line_type = s.line_type
        AND d.price_code =s.price_code )
   WHEN MATCHED THEN UPDATE SET
    d.APPLICATION_ID='CPMASI',
    d.SYS_UPDATE_DATE=SYSDATE,
    d.OPERATOR_ID=nvl(s.OPERATOR_ID,  d.OPERATOR_ID),
    d.LOCATION_ID=nvl(s.LOCATION_ID,d.LOCATION_ID),
    d.ITEM_ID= nvl(s.ITEM_ID,d.ITEM_ID),
    d.LINE_TYPE= nvl(s. LINE_TYPE, d.LINE_TYPE),
    d.EXPIRATION_DATE=nvl(s.EXPIRATION_DATE,d.EXPIRATION_DATE),
    d.PRICE_CODE= nvl(s.PRICE_CODE,d.PRICE_CODE),
    d.TO_QTY=nvl(s.TO_QTY,d.TO_QTY),
    d.PRICE= nvl(s.PRICE,d.PRICE),
    d.CHARGE_CODE=nvl(s.CHARGE_CODE,d.CHARGE_CODE),
    d.SOC=nvl(s.SOC,d.SOC), 
    d.COMMITMENT=nvl(s.COMMITMENT,d.COMMITMENT), 
    d.CAMBIAZO_CODE=nvl(s.CAMBIAZO_CODE,d.CAMBIAZO_CODE),  
    d.PPG_IND=nvl(s.PPG_IND,d.PPG_IND);

This gets: 得到:

SQL Error: ORA-00905: missing keyword
00905. 00000 -  "missing keyword"

If this isn't possible in 9i, then how would I do an equivalent update instead? 如果在9i中无法做到这一点,那么我将如何进行等效更新?

The syntax diagram for 9i shows that you had to have both when matched and when not matched clauses. 9i的语法图显示,必须when matchedwhen not matched子句同时具有。 That changed in 10gR1 (and is mentioned in the new features list); 这在10gR1中有所更改 (并在新功能列表中提到); but that doesn't really help you if you can't upgrade - it just explains why it doesn't work. 但是,如果您无法升级,那对您没有真正的帮助-只是解释了为什么它不起作用。 You were also trying to update two of the three columns from the join clause, which isn't allowed. 您还试图从join子句更新三列中的两列,这是不允许的。

You can do a correlated update instead: 您可以改为进行相关更新:

UPDATE CDLREFWORK.pricing d
SET (d.APPLICATION_ID, d.SYS_UPDATE_DATE, d.OPERATOR_ID, d.LOCATION_ID,
  d.EXPIRATION_DATE, d.PRICE_CODE, d.TO_QTY, d.PRICE, d.CHARGE_CODE, d.SOC,
  d.COMMITMENT, d.CAMBIAZO_CODE, d.PPG_IND)
= (
  SELECT 'CPMASI',
    SYSDATE,
    nvl(s.OPERATOR_ID,  d.OPERATOR_ID),
    nvl(s.LOCATION_ID,d.LOCATION_ID),
    nvl(s.EXPIRATION_DATE,d.EXPIRATION_DATE),
    nvl(s.PRICE_CODE,d.PRICE_CODE),
    nvl(s.TO_QTY,d.TO_QTY),
    nvl(s.PRICE,d.PRICE),
    nvl(s.CHARGE_CODE,d.CHARGE_CODE),
    nvl(s.SOC,d.SOC), 
    nvl(s.COMMITMENT,d.COMMITMENT), 
    nvl(s.CAMBIAZO_CODE,d.CAMBIAZO_CODE),  
    nvl(s.PPG_IND,d.PPG_IND)
  FROM V_REC s
  WHERE s.item_id =d.item_id
  AND s.line_type = d.line_type
  AND s.price_code = d.price_code
)
WHERE EXISTS (
  SELECT null
  FROM V_REC s
  WHERE s.item_id =d.item_id
  AND s.line_type = d.line_type
  AND s.price_code = d.price_code
);

I've taken out the item_id and line_type columns as you already know they match. 我已经删除了item_idline_type列,因为您已经知道它们匹配。 The where exists clause means only rows in pricing which actually have a matching row in v_rec are updated. where exists v_rec子句意味着仅会更新pricing中实际上在v_rec中具有匹配行的行。 That may mean the nvl() calls are redundant, and you just need to select the value from s , but without knowing your data it's hard to be sure. 可能意味着nvl()调用是多余的,您只需要从s选择值,但是却不知道数据是很难确定的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM