Search code examples
sqloracle-databaseoracle10goracle-xe

MERGE and ON DELETE CASCADE in Oracle XE 10g


In short (tl;dr): When trying to delete rows during a MERGE, Oracle 10g seems to ignore ON DELETE CASCADE statements for foreign keys. I would like to know if this is a known bug, a feature (apparently discontinued in 11g), or what.

More in detail:
It seems to me that in Oracle XE 10g, trying to delete rows from a table within a MERGE statement leads to an ORA-02292 error (violation of referential integrity) whenever there is a foreign key referencing the destination table of the merge, even if ON DELETE CASCADE was specified in the foreign key constraint. For example, say I create three tables

CREATE TABLE Mysource(
  MykeyS NUMBER,
  MystringS VARCHAR2(10),
  CONSTRAINT Mysource_PK PRIMARY KEY(MykeyS) ENABLE
);

CREATE TABLE Mydest(
  MykeyD NUMBER,
  MystringD VARCHAR2(10),
  CONSTRAINT Mydest_PK PRIMARY KEY(MykeyD) ENABLE
);

CREATE TABLE Myother(
  Mykey NUMBER,
  Mydate DATE,
  CONSTRAINT Myother_FK FOREIGN KEY(Mykey)
  REFERENCES Mydest(MykeyD) ON DELETE CASCADE ENABLE
);

and insert some data in them, then try

MERGE INTO Mydest D
USING Mysource S
ON (D.MykeyD=S.MykeyS)
WHEN MATCHED THEN
UPDATE SET D.MystringD = S.MystringS
DELETE WHERE (S.MykeyS > 10)
WHEN NOT MATCHED THEN
INSERT (MykeyD, MystringD)
VALUES (S.MykeyS, S.MystringS)
WHERE (S.MykeyS <= 10)

If both Mydest and Myother had some rows with >10 key, the attempted MERGE would then result in an ORA-02292, claiming a violation of the Myother_FK constraint. This sounds illogical to me (I can delete rows from Mydest using a direct DELETE, but not with a MERGE?), and in fact it does not seem to happen with Oracle XE 11g.

Question: Do you know if this is a known bug, or a weird feature? Or am I missing something, maybe? Searching the internet has not helped much, so far.


Solution

  • Oracle has it listed as bug 8268746 in 10.2.0.3. It is fixed in 11.2. The document is not available for linking externally, but it provides a test case similar to the example provided in the question above. The work-around is to not use the merge statement (or upgrade to 11.2).