3

I can not provide any code, so I try to be as precise as I can explaining how code works.

There is a process: some inserts, some updates etc. etc.. At some point there is a dbms_sql.execute procedure in use.

In this execute there is a statement which contains:

SELECT * from table(fun_get_data)

returning global type

CREATE OR REPLACE TYPE t_data_tab AS table of t__data_rec;

In function fun_get_data there is a "cache tool" - when executing for the 1st time, loading data to cache, then returns it every other time. Problem is, that when dbms_sql.execute is in fire - it not sees uncommited data.

I even put a session id in log- everything works in same session and #serial.

Am i missing something? Is dbms_sql works as an autonomous transaction?

Edit: I did some deeper digging. Turns out, when oracle executing dynamic statement and it looks like

with data_ (select * from table(fun_get_data))
Select ...
from   data_ d1
...

it not sees uncommited data, but when i modified SQL to this:

select ...
from (select * from table(fun_get_data))

everything is ok.

Any idea?

EDIT2: some deeper digging. It seems that

with data_ (select * from table(fun_get_data))
Select ...
from   data_ d1
left   join data_ d2
       on d1.id = d2.id
...

if any kind of join appear in query(left, simple join or data_ d1, data_ d2 where), then uncommited data not exists. Without left join works... Dark magic truly..

q4za4
  • 630
  • 4
  • 12
  • 2
    No, dbms_sql isn't autonomous, it's just dynamic. Perhaps the function's first call is just earlier than you think, before any data changes are made in that session; or the caching isn't as session-specific, or transaction-specific, as you might be assuming. But wild guesses aren't going to be very helpful. You probably need to create a [mcve] that demonstrates the effect you are seeing - and just creating that may well show you what's going on in your real code. – Alex Poole Jan 18 '22 at 12:38
  • 1
    I also checked, I put every few steps select count(1) from table, and it shows count(1) := 1 until reaches this dbms_sql.execute. Inside it shows count(1) := 0... – q4za4 Jan 18 '22 at 12:45
  • 1
    Well, [here's a simple demo](https://dbfiddle.uk/?rdbms=oracle_18&fiddle=3438a1be060dcb168b6e85a92aef155e) showing that dbms_sql sees uncommitted data and so isn't autonomous. Maybe something else is - `fun_get_data`, or the code you're executing dynamically. Again, we really need to see a [mcve]. – Alex Poole Jan 18 '22 at 13:00
  • 1
    @AlexPoole - I've updated my question. Please take a look, thanks :) – q4za4 Jan 18 '22 at 17:26
  • Which version and patch level of Oracle you seeing that in? And is there are committed data - if so is it picking that up? (I'm guessing not, from your count 0 comment). It's possible you're hitting a bug with CTEs and table collection expressions. – Alex Poole Jan 18 '22 at 17:34
  • Is there a procedure or function declared as autonomous transaction, wich is involved in the query? If yes, it still runs in the same session, but doesn't see any data modified in the current transaction. – D. Mika Jan 18 '22 at 18:21
  • @D.Mika - no, function is not autonomous. – q4za4 Jan 18 '22 at 22:50
  • @AlexPoole - if data is commited - everything works perfect. From registry$sqlpatch: DATABASE RELEASE UPDATE 12.2.0.1.180116 – q4za4 Jan 18 '22 at 22:50
  • 1
    Kind of a long shot, but you are describing something _very_ similar to bug 13253977 (see also: bug 15889476). But those bugs should be fixed in your version. You might try this before testing: `alter system set "_FIX_CONTROL"="13253977:ON";` Alternatively, add the `/*+ INLINE */` hint to your `WITH` clause. I.e., `with /*+ INLINE */ data_ (select * from table(fun_get_data))`. – Matthew McPeak Jan 18 '22 at 23:27
  • @MatthewMcPeak Tried, but no :/ Did some greater diggind, updated my question – q4za4 Jan 19 '22 at 06:02
  • 1
    This was an Oracle bug until release 12.1.0.1. Perhaps the `LEFT JOIN` is a wrinkle that Oracle left unfixed? Not sure. It sounds like you could easily put together a minimal, reproducible example to illustrate the bug. If you did that, people here could at least help you confirm that it's an Oracle bug. Of course, there is no need to `LEFT JOIN` a table to itself using the same column, assuming `id` is unique. Are you sure the `LEFT JOIN` is necessary? – Matthew McPeak Jan 19 '22 at 11:41
  • This does look very much like the bug Matthew identified (or one from its long history). This effect is [reproducible in 11.2.0.2](https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=6e7aa25aee51586103c14e99627eb8b0), but *is* mitigated there with the `inline` hint; and according to MoS you shouldn't be seeing in in 12.2.0.1 anyway. I don't have a 12.2 database, but it's [OK in 18c](https://dbfiddle.uk/?rdbms=oracle_18&fiddle=3119a351b3a82eea041ee5ace1493827). Oracle support may be able to identify which bug it actually is. – Alex Poole Jan 19 '22 at 17:27

0 Answers0