简体   繁体   English

如何使用Merge语句更新目标表

[英]How to update a target table with Merge statement

I'm trying to update a column in target table using merge statement by joining target table with source tables and getting the following error. 我试图通过将目标表与源表联接并使用以下错误,使用merge语句更新目标表中的列。

I need to compare a offer_id, order_Date and Doc_receipt_date from TRADE table with offer_trade_by_date, offer_start_date, offer_end_date. 我需要将TRADE表中的offer_id,order_Date和Doc_receipt_date与offer_trade_by_date,offer_start_date,offer_end_date进行比较。 Here I'm trying to verify the trade is done with in the time period. 在这里,我试图验证交易是否在该时间段内完成。 If TRADE is done in time then it's pass the check (ie 'Y'). 如果交易及时完成,则通过检查(即“ Y”)。 If TRADE is not done in time then it didn't pass the check (ie 'N'). 如果未及时进行贸易,则它未通过检查(即“ N”)。 If we don't have any information to check the condition (ie when DOCK_RECEIPT_DATE is NULL) then ('X'). 如果我们没有任何信息可以检查条件(即,当DOCK_RECEIPT_DATE为NULL时),然后('X')。 To achieve this check I wrote below code and getting the following error. 为了实现此检查,我编写了以下代码并得到以下错误。

ORA: 30926 unable to get a stable set of rows in the source table. ORA:30926无法在源表中获得稳定的行集。

Check the data in my tables below. 检查下表中的数据。

TRADE / Target table 贸易/目标表

KEYID      DPBL_OFFER      ORD_DATE    DOC_RECPT_DT     TRADE_DATE_MET

 1          107           30-SEP-17     01-JAN-17              X
 2          107           22-SEP-17      NULL                  X
 3          107           07-OCT-17      NULL                  X
 4          107           24-NOV-17     28-NOV-17              X
 5          106           24-AUG-17     11-SEP-17              X
 6          105           11-JUN-17       NULL                 X
 7          108           05-SEP-17     13-SEP-17              X
 8          109           28-JUL-17     10-AUG-17              X
 9          110           01-SEP-17     14-SEP-17              X

PROD_OFFER /Source table) PROD_OFFER /来源表)

Offer_id                Trade_by_Date
 106                      14-OCT-17
 107                      14-NOV-17
 105                      02-AUG-17
 108                      18-NOV-17
 109                      14-OCT-17
 110                      18-NOV-17

OFFER_START_END_V /Source Table 2) OFFER_START_END_V /来源表2)

Offer_id      Offer_Period   Offer_Start_Date    Offer_End_Date
  106             1             27-JUL-17          27-JUL-17
  106             2             28-JUL-17          14-OCT-17
  107             1             15-SEP-17          23-JAN-18
  105             1             01-JUN-17          02-AUG-17
  108             1             23-AUG-17          14-SEP-17
  108             2             16-SEP-17          19-SEP-17
  110             1             23-AUG-17          14-SEP-17
  110             2             16-SEP-17          19-SEP-17 
  109             1             02-JUL-17          12-NOV-17

Here keyid in my target table is PK and DPBL_OFFER id is offer_id from target table and isn't FK. 我的目标表中的keyid是PK,DPBL_OFFER id是目标表中的offer_id,不是FK。

Check below code 检查下面的代码

MERGE INTO TRADE TB
   USING (
            SELECT T1.KEYID, T1.DPBL_OFFER
              , CASE WHEN T1.ORD_DATE >= T3.OFFER_START_DATE AND
                          T1.ORD_DATE <= T2.TRADE_BY_DATE AND
                          T1.COD_RECPT_DATE <= T3.OFFER_END_DATE
                     THEN 'Y'
               WHEN T1.ORD_DATE < T3.OFFER_START_DATE AND
                          T1.ORD_DATE > T2.TRADE_BY_DATE AND
                          T1.COD_RECPT_DATE > T3.OFFER_END_DATE
                THEN 'N'
            ELSE 'X'
           END AS TRADE_DATE_MET
         FROM TRADE T1
         JOIN PROD_OFFER  T2
               ON T1.DPBL_OFFER_ID = T2.OFFER_ID
          JOIN OFFER_START_END_V T3
                ON T1.DPBL_OFFER_ID = T3.OFFER_ID) JT

        ON TB.KEYID  = JT.KEYID
          AND TB.DPBL_OFFER_ID = JT.OFFER_ID
WHEN MATCH THEN
         UPDATE SET TB. TRADE_DATE_MET = JT.TRADE_DATE_MET;

Can some one help me to overcome this error.? 有人可以帮助我克服这一错误吗?

FYI:- I'm using Oracle 11g. 仅供参考:-我正在使用Oracle 11g。

That error generally means that there is at least one row in the target table (at least one, there may be many) for which there are at least TWO different rows in the source table (or result of three-table join, in your case) satisfying the ON condition(s) in the MERGE statement - and for which the values used in the UPDATE clause are actually different. 该错误通常表示目标表中至少有一行(至少一行,可能有很多行),而在源表中至少有两行不同(在您的情况下为三表联接的结果) )满足MERGE语句中的ON条件,并且UPDATE子句中使用的值实际上不同。

In your case: for KEYID = 5, DPBL_OFFER is 106. This joins to one row in PROD_OFFER and two different rows in OFFER_START_END_V. 在您的情况下:对于KEYID = 5,DPBL_OFFER为106。这将连接到PROD_OFFER中的一行和OFFER_START_END_V中的行。 And the TRADE_END_MET is different for the two resulting rows in the three-table join. 对于三表联接中的两个结果行,TRADE_END_MET是不同的。 (Or, if it is the same - let's say 'N' for both - for this KEYID, then perhaps for KEYID= 7, with DPBL_OFFER = 108, which also joins to two different rows in the last table, the resulting TRADE_END_MET is not the same in both rows.) (或者,如果相同,对于这两个KEYID,如果都说'N',则对于KEYID = 7,DPBL_OFFER = 108,它也连接到最后一个表中的两个不同行,则得出的TRADE_END_MET不是两排相同。)

This kind of error is usually fatal, since it is in fact an error in logic, regardless of code (or even of language). 这种错误通常是致命的,因为实际上是逻辑错误,与代码(甚至语言)无关。 That is, even if you express the problem in common language and you try to solve it with paper and pencil, you can't, because it is self contradictory. 也就是说,即使您用通用语言表达问题,并尝试用纸和铅笔解决问题,也不会,因为这是自相矛盾的。

It is similar to, but more complicated than: Target table has columns ID (primary key) and FLAG (currently null). 它类似于但比其复杂:目标表具有列ID(主键)和FLAG(当前为null)。 Source has columns ID and flag. 源具有列ID和标志。 Target has one row (1, null). 目标有一行(1,空)。 Source has two rows, (1, 'Y') and (1, 'N'). 源有两行,(1,'Y')和(1,'N')。 You want to use the source to update the flag in the target. 您要使用源更新目标中的标志。 Do you see why that doesn't make sense? 您知道为什么这没有意义吗? This is exactly the kind of problem you are having. 这正是您遇到的问题。

Run the three-way join by itself (the "source table" for the MERGE) and inspect the TRADE_END_MET values for KEYID = 5 and 7 - you will likely find the problem. 单独运行三向联接(MERGE的“源表”),并检查TRADE_END_MET的KEYID = 5和7值-您可能会发现问题。

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

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