我尝试使用merge表更新目标表中的列,方法是将目标表与源表连接并获得以下错误。
我需要将TRADE表中的offer_id,order_Date和Doc_receipt_date与offer_trade_by_date,offer_start_date,offer_end_date进行比较。在这里,我试图验证交易是否在该时间段内完成。如果及时完成交易,则通过支票(即' Y')。如果没有及时完成交易,那么它没有通过支票(即' N')。如果我们没有任何信息来检查条件(即当DOCK_RECEIPT_DATE为NULL时),那么(' X')。为了实现这个检查,我在下面写了代码并得到以下错误。
ORA:30926无法在源表中获得稳定的行集。
检查下表中的数据。
贸易/目标表
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 /来源表)
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 /来源表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
此目标表中的keyid是PK,DPBL_OFFER id是来自目标表的offer_id,并且不是FK。
检查以下代码
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;
有人可以帮助我克服这个错误。?
仅供参考: - 我使用的是Oracle 11g。
答案 0 :(得分:0)
该错误通常意味着目标表中至少有一行(至少有一行,可能有很多行),源表中至少有两行不同的行(或三表连接的结果,在你的情况下)满足MERGE语句中的ON条件 - 并且UPDATE子句中使用的值实际上是不同的。
在您的情况下:对于KEYID = 5,DPBL_OFFER为106.这将加入PROD_OFFER中的一行和OFFER_START_END_V中的两个不同的行。并且TRADE_END_MET对于三表连接中的两个结果行是不同的。 (或者,如果它是相同的 - 让两个人说'N&#39;对于这个KEYID,那么也许对于KEYID = 7,DPBL_OFFER = 108,它也加入 2最后一个表中的不同行,得到的TRADE_END_MET在两行中都不相同。)
这种错误通常是致命的,因为它实际上是逻辑上的错误,无论代码(甚至语言)如何。也就是说,即使你用普通语言表达问题并且你试图用纸和笔来解决它,你也不能,因为它是自相矛盾的。
它类似于,但更复杂:目标表具有列ID(主键)和FLAG(当前为空)。源具有列ID和标志。 Target有一行(1,null)。来源有两行,(1,&#39; Y&#39;)和(1,&#39; N&#39;)。您希望使用源更新目标中的标志。你明白为什么这没有意义吗?这正是你遇到的那种问题。
单独运行三向连接(&#34;源表&#34;用于MERGE)并检查KEYID = 5和7的TRADE_END_MET值 - 您可能会发现问题。