Oracle SQL Auto-updating Table From a Different Database - oracle

I have two tables from different database, db1.names and db2.names_rep. db1.names is constantly getting new data and I need it to reflect in db2.names_rep.
I've created a dblink connecting for db1 in db2 named dblink_db1.
CREATE DATABASE LINK dblink_db1
CONNECT TO user IDENTIFIED BY pass
USING '(DESCRIPTION=
(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))
(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=SID)))';
and a trigger that calls the db1.names table
create or replace trigger "names_trigger"
after insert or update or delete on "names#dblink_db1"
for each row
begin
if inserting then
insert into "names_rep" (name_id, student_names)
values (:NEW.name_id, :NEW.student_names);
elsif updating then
update "names_rep"
set name_id=:NEW.name_id, student_names=:NEW.student_names
where name_id=:NEW.name_id;
elsif deleting then
delete from "names_rep"
where name_id=:OLD.name_id;
end if;
end;
The dblink is working as i can invoke this query successfully in db2
select * from names#dblink_db1
I'm receiving an error that says this
Error report: ORA-00942: table or view does not exist
00942. 00000 - "table or view does not exist"
*Cause:
*Action:
Lastly, I've read about Oracle Streams. Is that an alternative to Triggers? I'm hoping I don't have to specify each operation as to what is done in Trigger

You are trying to create a trigger in database db2 on a table in db1. I'm not sure that's possible.
I think the trigger needs to be created in db1, and to insert/update/delete rows over a link to db2.

Related

Referring to objects(tables) in other schema or user in Oracle procedure

Am accessing table data from other schema and inserting into current schema table in oracle procedure, but am unable to compile the procedure getting error "Error(5,27): PL/SQL: ORA-00942: table or view does not exist".
But where as when I select data from table(in other schema) directly am able to fetch the data but not in procedure. I have all required permissions as well.
Below is the procedure.
CREATE OR REPLACE PROCEDURE TEST_SCHEMA
IS
BEGIN
INSERT INTO table1
SELECT * FROM Other_User_Schema.Table2
COMMIT;
END;
It seems that you acquired privileges to select data from other_user_schema.table2 via role. If that's so, grant that privilege directly to your user because that won't work in named PL/SQL procedures.

Is there a way to tell if Oracle attempted an insert on a table from database logs?

We have a java application deployed on a production WebSphere server. The code is supposed to insert a row into a table, but it does not. I see no error messages in the application server logs. It is as if no attempt was made to insert the row. The same code deployed in a test environment does insert the row.
I would like to know if Oracle attempted to insert a row and then rolled it back for some reason. I am not familiar with Oracle at all. Is there a way to tell by looking at the database logs if an insert statement was executed on the table?
We are using Oracle 10
Thanks
You can use DML before insert trigger. This trigger will execute each time a row is inserted into the given table.
CREATE OR REPLACE TRIGGER t_log_insert
 BEFORE INSERT ON table_name
 FOR EACH ROW
 ENABLE
 BEGIN
--write your logic here.
  DBMS_OUTPUT.PUT_LINE('You Just Inserted a Row');
 END;
 /
You can read more about trigger here.

Stop SQL statements without schema qualifiers

How can I stop a SQL statement from running if it's missing a schema qualifier? Most of these issues are caught by a development process, but is there a way to stop the ones that slip through the cracks?
For example, this statement should work:
create table jheller.test_table(a number);
This statement should fail:
create table test_table(a number);
Most of these problems are easily caught during development. Usually a lack of privileges will cause an error like ORA-00942: table or view does not exist. Or if the statement runs successfully on the wrong schema it will cause an obvious error that will be caught during testing.
But inevitably some bad statements still make it into deployments that are promoted to the upper environments. This leads to broken deployments and invalid objects created in schemas like SYS. (We shouldn't be running so many deployments as SYS but that's beyond our control.)
It's not necessary to catch 100% of these issues. But catching 99.9% instead of 99% would make a significant difference.
SQL statements without schema qualifiers can be prevented by:
Creating a fake, empty schema on all databases.
Creating a database trigger to prevent creating objects in that schema.
Setting the session variable CURRENT_SCHEMA to that schema at the beginning of deployment scripts.
Installation - run once per database.
--Create a user. It won't be used so lock it and don't grant it any privileges.
create user schema_qualifier_required identified by "[SOME RANDOM PASSWORD HERE]";
alter user schema_qualifier_required account lock;
--Create trigger to prevent any other user from creating objects on it.
create or replace trigger schema_qualifier_required.no_objects_on_schema_qualifier
before ddl on database
/*
Purpose: SCHEMA_QUALIFIER_REQUIRED exists only to help prevent statements
without schema qualifiers. This trigger ensures no objects can be created in
the schema.
Run this command in a session to help ensure schema qualifiers are used:
alter session set current_schema=schema_qualifier_required;
To drop or modify the schema this trigger must be dropped like this:
alter system set "_system_trig_enabled"=false;
drop trigger schema_qualifier_required.no_objects_on_schema_qualifier
alter system set "_system_trig_enabled"=true;
*/
begin
if ora_dict_obj_owner = 'SCHEMA_QUALIFIER_REQUIRED' then
raise_application_error(-20000, 'You cannot create objects in this schema. '||
'Did you forget to use a schema qualifier in your statement?');
end if;
end;
/
Non-qualified statements initially work.
SQL> create table test1(a number);
Table created.
SQL> select * from test1;
no rows selected
ALTER SESSION to prevent future non-qualified statements from running.
SQL> alter session set current_schema=schema_qualifier_required;
Session altered.
Non-qualified statements no longer work.
SQL> create table test2(a number);
create table test2(a number)
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20000: You cannot create objects in this schema. Did you forget to use a
schema qualifier in your statement?
ORA-06512: at line 3
SQL> select * from test1;
select * from test1
*
ERROR at line 1:
ORA-00942: table or view does not exist
I have not used this method in production yet. If anyone sees problems with this approach or knows of a better way please edit, comment, or add another answer.

I created a Global Temp Table. I cannot Drop the table

In Unix, connecting to oracle server, I create a temp table on commit preserve rows. I then first truncate the table then I go to drop the table. Trying to drop the table I receive the following error:
ORA-14452: attempt to create, alter or drop an index on temporary table already in use (DBD ERROR: error possibly near <> indicator at char 11 in 'drop table <>temp01')
I cannot end session using Kill through commands because I do not have permission.
Seems to me, the error is pretty clear:
$ oerr ora 14452
14452, 00000, "attempt to create, alter or drop an index on temporary table already in use"
// *Cause: An attempt was made to create, alter or drop an index on temporary
// table which is already in use.
// *Action: All the sessions using the session-specific temporary table have
// to truncate table and all the transactions using transaction
// specific temporary table have to end their transactions.
So, make sure that all sessions are not using the table. If even one other session is using the table, You will get this error, and won't be able to drop it.

Oracle - Unable to drop tables

This question is related to the one I posted yesterday but with further implications.
The situation is: I'm unable to drop ANY table. Here's an example:
SQL> CREATE TABLE FOO (BAR NUMBER) TABLESPACE SYSTEM
/
Table created.
SQL> SELECT COUNT(1) FROM FOO;
COUNT(1)
----------
0
SQL> DROP TABLE FOO;
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-00942: table or view does not exist
ORA-06512: at line 19
So, the table seems to exist but I'm not capable of dropping it.
Notice the error ORA-00604: error occurred at recursive SQL level 1. If I try to drop a non existing table, this error does not appear:
SQL> DROP TABLE NON_EXISTING_TABLE
ERROR at line 1:
ORA-00942: table or view does not exist
Somehow, the system is unable to find the table at dropping time.
The oracle installation and the DB itself is new (one day old).
EDIT - I retried this test using another tablespace and user (I just created ones) and I got a slightly different behaviour: using SYS, after I got the DROP error I can still SELECT from the table. However, using this new user, after I got the DROP error, I no longer can SELECT from the table.
Solution
We found the problem: the MDSYS.SDO_GEOR_SYSDATA_TABLE was missing, preventing the drop operation.The solution is to restore that table. Here is the complete solution, by Gaurav Soni (by the way, many thanks).
Run the script catmd.sql (located in $ORACLE_HOME/md/admin dir).
The catmd.sql script is the script that loads all objects needed by Oracle spatial in the database. Then drop the user.
you can also refer to oracle metalinks
Steps for Manual Installation of Oracle Spatial Data Option
Dropping user results in ORA-942 against SDO_GEOM_METADATA_TABLE
I'd suggest that you activate SQL tracing (ALTER SESSION SET SQL_TRACE=TRUE;) and try the drop again. This will generate a trace file on the server (in the udump directory) that will show all the SQL the session executed, including recursive statements. This should show you the recursive SQL statement that is failing.
I think the problem is that you created the table on system tablespace. You should create it on the user tablespace or create one to store your data.

Resources