we have a strange problem here, we can’t explain to ourselves.
We have a view in an Oracle DB Version 10.2.0.5.8. The view uses an INSTEAD OF trigger.
This is the code for the trigger:
CREATE OR REPLACE TRIGGER V1_T1_BIUD
INSTEAD OF INSERT OR UPDATE OR DELETE
ON V1_T1
FOR EACH ROW
DECLARE
AnyId NUMBER;
BEGIN
IF INSERTING THEN
INSERT INTO Table T1 (
F1, F2, F3, F4, F5
) VALUES (
:new.F1, :new.F2, :new.F3, :new.F4, :new.F5
);
ELSIF UPDATING THEN
UPDATE T1 SET F1 = :new.F1,
F2 = :new.F2,
F3 = :new.F3,
F4 = :new.F4,
F5 = :new.F5
WHERE F1 = :old.F1;
ELSIF DELETING THEN
DELETE FROM T1
WHERE F1 = :old.F1;
END IF;
END;
/
This is an example INSERT statement:
INSERT INTO V_T1 (
F1, F2, F3, F4, F5
)
SELECT A.V, A.S, A.F, A.T, A.Z
FROM (
SELECT 'E' V, 'N' S, 'ABC' F, 'E' T, 'E' Z FROM DUAL UNION ALL
SELECT 'E', 'Y', 'QWE', 'O', 'E' FROM DUAL UNION ALL
SELECT 'I', 'Y', 'GHJ', 'I', 'I' FROM DUAL
) A
ORDER BY 1, 2, 3;
COMMIT;
Pay attention to the ORDER BY clause at the end of the select. The result of this INSERT statement is something like this:
F1 F2 F3 F4 F5
---------------
E N ABC I I
E Y QWE I I
I Y GHJ I I
As you can see, the 4th and 5th column are incorrectly filled with the values of the last datarow in all other datarows.
If we change the INSERT statement like this:
INSERT INTO V_T1 (
F1, F2, F3, F4, F5
)
SELECT A.V, A.S, A.F, A.T, A.Z
FROM (
SELECT 'E' V, 'N' S, 'ABC' F, 'E' T, 'E' Z FROM DUAL UNION ALL
SELECT 'E', 'Y', 'QWE', 'O', 'E' FROM DUAL UNION ALL
SELECT 'I', 'Y', 'GHJ', 'I', 'I' FROM DUAL
) A
ORDER BY 1, 2, 3, 4, 5;
COMMIT;
the result is this:
F1 F2 F3 F4 F5
---------------
E N ABC E E
E Y QWE O E
I Y GHJ I I
Again, pay attention to the ORDER BY clause, which now orders all rows instead of the first three in the first insert statement.
edit: If you omit the ORDER BY clause the result is also as expected (e. g. like in example 2).
Can someone explain this behaviour to me?
P. S. Concerning the comments:
I have not time to investigate or deliver any more infos on this topic today. I will create a complete example on our database and publish it here in the next few days. Thank you for your patience!
This does look like a bug, but I can’t find an obvious match in the bug database (a few look possible, like 5842445, but are vague or don’t quite line up). I can only make it happen with the trigger (so I assume your inserts being against
T1rather thanV1_T1are a transcription error); and only ifF4andF5areCHARnotVARCHAR2:… and the
instead oftrigger exactly as shown in the question.The
:NEWvalues inside the trigger are wrong, according toDBMS_OUTPUT, but how that’s affected by the column data type is something only Oracle would be able to figure out I think.It also still happens in 11.2.0.3 (Linux). Interestingly if I change the
UNION ALLto justUNIONI get slightly different results; in 10g the two columns end up null, in 11g they havex:… which is even stranger – looks like maybe a fix to some other bug has slightly affected this one.
So not really an answer; you’d need to rase a service request with Oracle, and I’m fairly sure they’d just tell you to remove the
order bysince it doesn’t have any value, as you already know.For Thilo; plan without any
order by(11g):And plan with
order by 1,2,3or1,2,3,4,5– same plan hash value (11g):And I see the same sort of corruption selecting from other tables, but only if the results in the subquery are unioned before being ordered; though then I get nulls rather than
x. (I briefly wondered if thexwas coming fromdualitself, butdummyis upper-caseX, and this shows lower-casex).Following @Annjawn’s comment, changing the insert from
V1_T1to a direct insert inT1works fine (i.e. correct values inserted), and curiously has the same plan hash even though it shows the table name instead of the view in theNamecolumn. Work with eitherUNIONorUNION ALL, too, and in both 10gR2 and 11gR2. Seems to be the trigger that’s confused by the union, I guess.Further to the datatype point… the view has to have
charcolumns, the table does not necessarily, which isn’t really a surprise since the trigger on the view seems to be the problem. If I set the table up withcharcolumns but cast them tovarchar2in the view then I don’t see the problem:But If I do it the other way around it does exhibit the problem: