Something very strange has happened since we migrated our schemas/database from 12c to 19c
When I insert records to a table and I check the row count
namely under my oracle user - say SMITH_J - I see 4 records. Good I am happy.
When my Java application looks at the same table which I will call QUEUE_TAB - using the application oracle user - say APP_TOMCAT - it just sees ZERO records. How can that be ?
I check the GRANTS for APP_TOMCAT - it has everything that should be there for that table - it's got SELECT,INSERT,UPDATE,DELETE - which it had before.
What is really perplexing why are the record counts different - despite all the privileges being the same ? Is there something here that I have overlooked OR cannot see at the moment ? Is it something to do with privileges going from 12c to 19c ?
I owe the correct answer to Alex Poole in the comments above.
I was using a procedure to populate the table in question. And, foolishly assumed that the procedure would commit it. Of, course, it would have if it DID have a COMMIT within the code at the end of the procedure. So, after EXECUTING the procedure - I issued a COMMIT and it worked.
It's best practice NOT to have a COMMIT statement within your procedure even if it is a single procedure. See the comments of #MTO and #Alex Poole below
Related
Oracle Forms 10g - 'NULLS' is not accepted.
In program unit(PL/SQL Code) I use NULLS FIRST and its throwing error.
Encountered the symbol NULLS
select line_id
from oe_order_lines_all
where rownum <5
order by line_id NULLS FIRST;
kindly help
I am not familiar with forms, but a simple workaround (if it works) is to modify the order by clause. For example, assuming the line id's are positive, or at least non-negative, you could
order by nvl(line_id, -1)
The flavour of PL/SQL and SQL used in Forms is different and somewhat older than the one available in the database. Being able to run code on the database does not mean it will run without changes in Forms. Analytic functions is an example of a newer SQL feature which is missing in Forms. But you can always put your code into a PL/SQL package in the database and call it from your forms code.
I have the same database on 2 different Oracle servers, one is 11.2.0.1.0 and the other is 11.2.0.4.0.
I have the same 2 geometry tables in both databases and run the following query on both servers. When run on an 11.2.0.1.0 version of Oracle, the query runs for a few minutes and I get results, the same query when run on 11.2.0.4.0 runs for about 3 seconds and returns no results.
The BLPUs table holds 36 million points and the PD_B2 table holds a polygon. I am trying to find all the points that fall in the polygon.
Other spatial queries do return rows but it takes hours and hours whereas the table join suggested in the Oracle Spatial documentation, takes 15 minutes to return all the points.
SELECT /*+ ordered */ a.uprn
FROM TABLE(SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC','mask=ANYINTERACT')) c, blpus a, PD_B2 b
WHERE c.rowid1 = a.rowid
AND c.rowid2 = b.rowid;
The spatial queryies below return SDO_ROWIDSET() when run on the 11.2.0.4 server
select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC','mask=ANYINTERACT')
from dual;
select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC')
from dual;
On the 11.2.0.1 server they return results.
I have discovered that a much smaller table of points will work on 11.2.0.4 so it seems that there is a size limit on 11.2.0.4 when using SDO_JOIN where as 11.2.0.1 seems to cope with the large table.
Does anyone know why this is or if there is an actual limit on table size when using SDO_JOIN?
This is strange. I see no reason why SDO_JOIN will not work the same way in 11.2.0.4. At least I have not seen that sort of behavior before. It looks like a bug to me and I suggest you file a service request with Oracle Support so we can take a look. You may need to provide a dump of the tables - or at least of a small enough subset that demonstrates the problem.
That said there are a few things to check: did you apply the 11.2.0.4 patch on the same database ? I.e. nothing changed in terms of table structures or content, grants, etc ?
When you say that the query returns no rows, does it do so immediately ? Or does it perform some processing before completing without anything being returned ?
How large is the PD_B2 table ?
What happens when you do:
select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC','mask=ANYINTERACT')
from dual;
Does this also return nothing ?
What happens if you do
select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC')
from dual;
Both should return something that looks like this:
SDO_ROWIDSET(SDO_ROWIDPAIR('AAAW3LAAGAAAADmAAu', 'AAAW3TAAGAAAAg7AAC'), SDO_ROWIDPAIR('AAAW3LAAGAAAADmABE', 'AAAW3TAAGAAAAgrAAA'),...)
You will see this if you run the query in sqlplus. [If you use a GUI (like TOAD or SQLDeveloper) then you may not see that. All those GUIs have problems dealing with objects or arrays.]
But the fact that your 11.2.0.4 tests complete very quickly probably means that you get an empty result back, maybe like this:
SDO_ROWIDSET()
and that confirms that something did not work.
Now, from what you say PD_B2 only contains one row ? If so then there is no reason whatsoever to go via SDO_JOIN. A straightforward spatial query is easier to write. SDO_JOIN only makes sense when both tables being joined contain multiple rows. Then again, if one of the tables is very small (like the PD_B2 table in your case), then it anyway falls back to a simple query.
A simple query would look like this:
SELECT a.uprn
FROM blpus a, PD_B2 b
WHERE sdo_anyinteract (a.geoloc, b.geoloc) = 'TRUE';
Does this return what you expect in 11.2.0.4 ?
You may also want to examine the cost of the query and the query plan used. In sqlplus, do this:
set timing on
set autotrace traceonly
then run the above query. The effect is that sqlplus will not display any results - but it will still fetch and format the output: it will just not print them. At the end you will get a printout of the query plan used as well as some execution statistics and the elapsed time. Please add those results to your question.
Running the query from within your application should have a similar profile: similar response time and database-side costs - assuming you do fetch all the 1.3 million rows.
BTW, what do you do with those results ? Do you show them out as a report ? Do you save them into a table for later analysis ? Surely you do not want to show them all on a map ?
To clarify: SDO_JOIN is only for matching many to many geometries. For matching one to many, the simple SDO_ANYINTERACT() is what you need. As a matter of fact, SDO_JOIN will automatically fall back to a simple SDO_ANYINTERACT when one of the sets is very much smaller than the other. I can't see how SDO_JOIN could be faster in your circumstances (i.e. when searching for all objects that match one object) since it will perform the same as an SDO_ANYINTERACT and will require extra joins to the two tables.
Going back to the original issue - that of a difference in behavior in SDO_JOIN between 11.2.0.1 and 11.2.0.4 that IMO is definitely a bug that you need to report to Oracle Support.
In Oracle 11.2.0.1.0:
1) I created a table.
create table m1(id number(5,2), version number(5,2), primary key (id));
2) I created a sequence.
CREATE SEQUENCE m1_id_sq;
3) I inserted values into the table.
insert into m1(id, version) values (m1_id_sq.nextval, 1);
4) output.
id version
-------------
2 1
*I understand the reason for id=2 is due to deferred_segment_creation feature introduced from 11.2.0.1.0 onwards.
*I created an user instance in oracle and I ran the above three commands. Not as a master.
Now I follow the same steps
in Oracle 11.2.0.2.0,
but the output I got is,
id version
-------------
1 1
Please explain why the id=1 in oracle 11.2.0.2.0 whereas id=2 in oracle 11.2.0.1.0. Great thanks!
The problem may have to due with the fact that NOORDER is the default with Oracle Sequences, especially if you're running a RAC environment.
http://docs.oracle.com/cd/B12037_01/server.101/b10759/statements_6014.htm
I've learned that with Sequences, if I want to guarantee that they be sequential I usually have to add the following keywords when creating the sequence:
CREATE SEQUENCE m1_id_sq ORDER NOCACHE;
Edit to refer to above comments:
As noted by Alex Poole in the comments above:
"This shouldn't really matter anyway - you'll get gaps in sequences
for other reasons so you shouldn't rely on it starting with 1"
The NOORDER being the default for sequences explains this issue.
Alex Poole also noted a known issue: Oracle Note 1050193.1 (requires an Oracle Support account) related to an issue with deferred_segment_creation=TRUE
ThinkJet also refers to the following articles:
http://orawin.info/blog/2010/04/25/new-features-new-defaults-new-side-effects/
http://orawin.info/blog/2011/11/17/new-defaults-old-side-effects/
I'm using Oracle 10g (XE 10.2.0.1.0), and find a behavior that I don't understand:
select *
from employees manager
join employees worker on MANAGER.EMPLOYEE_ID = WORKER.MANAGER_ID
join departments on DEPARTMENTS.manager_id = 108
where
department_id = 100
;
The problem is I think Oracle should have complain about the ambiguity of department_id in the where clause, since it's a column in both the table employees and departments. The fact is in Oracle 10g, it doesn't, and the result shows that it interprets the department_id as the one in departments. However, if I comment out the second join statement (4th line above), Oracle does complain “ORA-00918: column ambiguously defined” as expected.
So, can somebody help to explain how the ambiguity is defined in Oracle 10g? Or perhaps this is a bug in 10g?
BTW: The tables are defined in the default HR schema bundled in the Oracle 10g.
Update: Just found a related post:
Why does Oracle SQL mysteriously resolve ambiguity in one joins and does not in others
I believe it is a bug in Oracle 10g that Oracle chose not to fix. When we were upgrading our applications from 10g to 11gR2, we found a couple of queries that were written "loosely" in respect of ambiguous column names but worked in Oracle 10g. They all stopped working in 11gR2. We contacted Oracle but they pretty much said that the tolerant behavior toward ambiguous column names is a correct behavior for Oracle 10g and the stringent behavior is the correct behavior for 11g.
I think it is, because departments have no alias. Therefore everything without being qualified by an <alias>. is first treated to be from departments.
So I also think when you give departments an alias you should get the ORA-00918 again. Cannot test here though...
Can I find out when the last INSERT, UPDATE or DELETE statement was performed on a table in an Oracle database and if so, how?
A little background: The Oracle version is 10g. I have a batch application that runs regularly, reads data from a single Oracle table and writes it into a file. I would like to skip this if the data hasn't changed since the last time the job ran.
The application is written in C++ and communicates with Oracle via OCI. It logs into Oracle with a "normal" user, so I can't use any special admin stuff.
Edit: Okay, "Special Admin Stuff" wasn't exactly a good description. What I mean is: I can't do anything besides SELECTing from tables and calling stored procedures. Changing anything about the database itself (like adding triggers), is sadly not an option if want to get it done before 2010.
I'm really late to this party but here's how I did it:
SELECT SCN_TO_TIMESTAMP(MAX(ora_rowscn)) from myTable;
It's close enough for my purposes.
Since you are on 10g, you could potentially use the ORA_ROWSCN pseudocolumn. That gives you an upper bound of the last SCN (system change number) that caused a change in the row. Since this is an increasing sequence, you could store off the maximum ORA_ROWSCN that you've seen and then look only for data with an SCN greater than that.
By default, ORA_ROWSCN is actually maintained at the block level, so a change to any row in a block will change the ORA_ROWSCN for all rows in the block. This is probably quite sufficient if the intention is to minimize the number of rows you process multiple times with no changes if we're talking about "normal" data access patterns. You can rebuild the table with ROWDEPENDENCIES which will cause the ORA_ROWSCN to be tracked at the row level, which gives you more granular information but requires a one-time effort to rebuild the table.
Another option would be to configure something like Change Data Capture (CDC) and to make your OCI application a subscriber to changes to the table, but that also requires a one-time effort to configure CDC.
Ask your DBA about auditing. He can start an audit with a simple command like :
AUDIT INSERT ON user.table
Then you can query the table USER_AUDIT_OBJECT to determine if there has been an insert on your table since the last export.
google for Oracle auditing for more info...
SELECT * FROM all_tab_modifications;
Could you run a checksum of some sort on the result and store that locally? Then when your application queries the database, you can compare its checksum and determine if you should import it?
It looks like you may be able to use the ORA_HASH function to accomplish this.
Update: Another good resource: 10g’s ORA_HASH function to determine if two Oracle tables’ data are equal
Oracle can watch tables for changes and when a change occurs can execute a callback function in PL/SQL or OCI. The callback gets an object that's a collection of tables which changed, and that has a collection of rowid which changed, and the type of action, Ins, upd, del.
So you don't even go to the table, you sit and wait to be called. You'll only go if there are changes to write.
It's called Database Change Notification. It's much simpler than CDC as Justin mentioned, but both require some fancy admin stuff. The good part is that neither of these require changes to the APPLICATION.
The caveat is that CDC is fine for high volume tables, DCN is not.
If the auditing is enabled on the server, just simply use
SELECT *
FROM ALL_TAB_MODIFICATIONS
WHERE TABLE_NAME IN ()
You would need to add a trigger on insert, update, delete that sets a value in another table to sysdate.
When you run application, it would read the value and save it somewhere so that the next time it is run it has a reference to compare.
Would you consider that "Special Admin Stuff"?
It would be better to describe what you're actually doing so you get clearer answers.
How long does the batch process take to write the file? It may be easiest to let it go ahead and then compare the file against a copy of the file from the previous run to see if they are identical.
If any one is still looking for an answer they can use Oracle Database Change Notification feature coming with Oracle 10g. It requires CHANGE NOTIFICATION system privilege. You can register listeners when to trigger a notification back to the application.
Please use the below statement
select * from all_objects ao where ao.OBJECT_TYPE = 'TABLE' and ao.OWNER = 'YOUR_SCHEMA_NAME'