How to recreate public synonym "DUAL"? - oracle

Using SQLDeveloper 4.0.1.14 to create an export script (separate files & "drops" checked), it generated me those 4 lines among others in DROP.sql:
DROP SYNONYM "PUBLIC"."DUAL";
DROP SYNONYM "PUBLIC"."DBMS_SQL";
DROP SYNONYM "PUBLIC"."DBMS_LOCK";
DROP SYNONYM "PUBLIC"."DBMS_OUTPUT";
Now that I have accidentally passed the whole script using SYSTEM user, I can no longer do modification (create or drop tables) to the database, I have that error popping:
An error was encountered performing the requested operation:
ORA-00604: error occurred at recursive SQL level 1
ORA-00942: table or view does not exist
00604. 00000 - "error occurred at recursive SQL level %s"
*Cause: An error occurred while processing a recursive SQL statement
(a statement applying to internal dictionary tables).
*Action: If the situation described in the next error on the stack
can be corrected, do so; otherwise contact Oracle Support.
Vendor code 604
The problem is that I'm getting that error event when I try this:
CREATE OR REPLACE PUBLIC SYNONYM "DUAL" FOR "SYS"."DUAL";
I precise that the SYS.DUAL table still exists as SELECT 1 FROM SYS.DUAL works but SELECT 1 FROM DUAL fails with ORA-00942: table or view does not exist.
I tried to recreate the synonym as SYSTEM and SYSDBA with the same failure.
Can I recreate those synonyms with another way?

Try it as SYS but without the doauble quotes, i.e.:
CREATE OR REPLACE PUBLIC SYNONYM DUAL FOR SYS.DUAL;
not
CREATE OR REPLACE PUBLIC SYNONYM "DUAL" FOR "SYS"."DUAL";
As I understand it the double quotes make the object name case sensitive.
Update - If you have access to metalink then you will find the answer in note 973260.1, something aboput a trigger firing :
ALTER SYSTEM SET "_SYSTEM_TRIG_ENABLED"=FALSE SCOPE=MEMORY;
CREATE OR REPLACE PUBLIC SYNONYM DUAL FOR SYS.DUAL;
ALTER SYSTEM SET "_SYSTEM_TRIG_ENABLED"=true SCOPE=MEMORY;
The note suggest that if this doesnt work, query DBA_TRIGGERS to find a BEFORE CREATE trigger enabled, and if found disable it and then re-issue create synonym statement, then re-enable the trigger.

Related

Create editionable view on Oracle

I am trying to create an ORACLE EDITIONABLE VIEW but I am getting the error:
SQL Error: ORA-00922: missing or invalid option
00922. 00000 - "missing or invalid option"
CREATE OR REPLACE FORCE EDITIONABLE VIEW "SCHEMA"."TABLE" ....
In https://docs.oracle.com/database/121/SQLRF/statements_8004.htm#SQLRF01504 is mentioned how u can create this kind of view.
If I remove EDITIONABLE the view is created without a problem.
Some advice will be welcomed :-)
Wrong syntax prbly
CREATE EDITIONING VIEW
You need oracle 11gR2 or higher
Also you need to enable Editions for user: (from here)
Enabling editions for a user is done using the ALTER USER command. This is not reversible. The result of this command can be seen by querying the EDITIONS_ENABLED column of the DBA_USERS view.
CONN / AS SYSDBA
ALTER USER edition_test ENABLE EDITIONS;

Solve problems with external table

I have problems with some Oracle external table
create table myExternalTable
(field1, field2....)
ORGANIZATION EXTERNAL
(TYPE ORACLE_LOADER
DEFAULT DIRECTORY myDirectory
ACCESS PARAMETERS
(RECORDS DELIMITED BY NEWLINE
NOLOGFILE
NOBADFILE
NODISCARDFILE
FIELDS TERMINATED BY '$')
LOCATION ('data.dsv'));
commit;
alter table myExternalTable reject limit unlimited; --solve reject limit reached problem
select * from myExternalTable;
When I select on the table I have this error :
ERROR at line 1:
ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error
KUP-04040: file data.dsv in myDirectory not found
It seems that the error description is not right because normally the table is already loaded with data.dsv when created.
Plus data.dsv exists in myDirectory.
What is going on? Can somebody help?
Note :
Instead of the select, this is what I normally do :
merge into myDatabaseTable
using
(select field1, field2,.... from myExternalTable) temp
on (temp.field1= myDatabaseTable.field1)
when matched then update
set myDatabaseTable.field1 = temp.field1,
myDatabaseTable.field2 = temp.field2,
......;
This works good on my development environment but on some other environment I have the error I said before :
ERROR at line 1:
ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error
KUP-04040: file data.dsv in myDirectory not found
First I thought that, in the environment it does not work, the directory did not point where it had to but selecting on dba_directories table, I could see the path of the directory is correct.
The problem is related with the access rights of the user on the operating system side. It is defined in Oracle Support Note Create Database Directory on Remote Share/Server (Doc ID 739772.1)
For my case, I created the directory with a sysdba and then for allowing other users to accesss that external table, I created another table which is creates by Create Table as Select statement for the external table. Otherwise, I need to map the Windows Oracle Service owner user to the exact Oracle user which is already defined in the note.
So, it is more like a well fitting workaround for my case.
To sum up the steps in a nutshell:
1- Create the external table T2
2- Create a table named T1 with CTAS to external table
3- Give SELECT right to T1
Hope this helps for your case.

ORA-00980 synonym translation no longer valid in PLSQL

I've got a synonym on a remote Oracle database that I can access in SQL over a database link, eg,
insert into my_table select * from my_synonym#my_database_link;
If I put the above statement into a PLSQL block, it won't compile, giving the error message "ORA-00980: synonym translation is no longer valid". The standard explanation is the table that the synonym points to has been dropped, etc, but this is not the case because the statement works in SQL.
If something works in SQL but not in PL/SQL then in most cases this is a problem with privileges.
Any privilege that a user received through a role is not active when you enter a PL/SQL block. So most probably the SELECT privilege on the underlying table was granted through a role and thus is not "active" in the PL/SQL block.
The usual cure for this is to grant the privileges directly to the user, not through a role.
Thank you to everyone who tried to help. This turned out to be an Oracle limitation:
https://support.oracle.com/rs?type=doc&id=453754.1
APPLIES TO:
PL/SQL - Version 9.2.0.8 and later Information in this document
applies to any platform.
Checked for relevance on 01-Apr-2015
SYMPTOMS
A PL/SQL block fails with error: ORA-00980: synonym translation is no
longer valid, when selecting data from a remote database. The
following code demonstrates this issue:
On DB3 (create the table)
CONNECT u3/u3 DROP TABLE tab; CREATE TABLE tab(c1 number); INSERT
INTO tab VALUES (1); COMMIT;
On DB2 (create a synonym to the table on DB3)
CONNECT u2/u2 DROP DATABASE LINK dblink2; CREATE DATABASE LINK
dblink2 CONNECT TO u3 IDENTIFIED BY u3 USING 'EMT102U6'; SELECT *
FROM global_name#dblink2; DROP SYNONYM syn2; CREATE SYNONYM syn2
FOR tab#dblink2; SELECT * FROM syn2;
On DB1 (create a synonym to the synonym on DB2)
CONNECT u1/u1 DROP DATABASE LINK dblink1; CREATE DATABASE LINK
dblink1 CONNECT TO u2 IDENTIFIED BY u2 USING 'EMT102W6'; SELECT *
FROM global_name#dblink1; DROP SYNONYM syn1; CREATE SYNONYM syn1
FOR syn2#dblink1; SELECT c1 from syn1;
This works in SQL but fails when called from PL/SQL
DECLARE num NUMBER; BEGIN SELECT c1 INTO num FROM syn1; END;
/
ERROR at line 4: ORA-06550: line 4, column 3: PL/SQL: ORA-00980:
synonym translation is no longer valid ORA-06550: line 4, column 3:
PL/SQL: SQL Statement ignored
CAUSE
This issue was reported in Bug 2829591 QUERING FROM A PL/SQL
PROCEDURE IN 9I -> 8I-> 7.3.4, GETTING ORA-980. This bug was closed
as 'NOT A BUG' for the following reasons
PL/SQL cannot instruct middle database (DB2) to follow the database
link during the compilation phase. Therefore in order for this PL/SQL
block to compile and run, both database links dblink1 and dblink2
should be defined on the front end database - DB1. During runtime
database link dblink2 will be looked up in DB2 as expected.
SOLUTION
To implement the solution, please execute the following steps:
Create a database link dblink2 on DB1 pointing to DB3
SQL> create database link dblink2 connect to u3 identified by u3 using
'EMT102U6';
Create and compile the PL/SQL block on DB1.
CREATE DATABASE LINK dblink2 CONNECT TO u3 IDENTIFIED BY u3 USING
'EMT102U6';
SELECT * FROM global_name#dblink2; DECLARE num NUMBER; BEGIN
SELECT c1 INTO num FROM syn1; END; / PL/SQL procedure successfully
completed.
TIP: Another option is to use dyanmic SQL in the PL/SQL block as a
work around. When using dynamic SQL the database link is not resolved
at compile time but at runtime.
Workaround solution is to use an Oracle view instead.
CREATE VIEW v_my_synomym as (select * from my_synonym#my_database_link);
Then reference the view in your package or procedure i.e.:
insert into my_table select * from v_my_synonym;
Check in remote database grants for "my_synonym" must be almost "select" for the user you use in connect string, check also the object which this synonym points at (maybe someone deleted the table).
I found this issue when owner of the table/view/procedure are not match with owner mentioned in SYNONYM.
Example : If owner of table TABLE_BRACH is ownerA and in Synonym mentioned table owner is something else (Not ownerA).
Solution:
1. Drop the SYNONYM
2. Create that with same name with correct owner.
CREATE PUBLIC SYNONYM BRANCH FOR ownerA.TABLE_BRACH ;

Oracle catldr.sql multiple errors

I'm preparing my new Oracle 11g install for "Direct" SQL*Loader operation. As per the documentation here:
http://docs.oracle.com/cd/B28359_01/server.111/b28319/ldr_modes.htm#i1007669
To prepare the database for direct path loads, you must run the setup script, catldr.sql, to create the necessary views. You need only run this script once for each database you plan to do direct loads to.
So I execute the following sql script:
$ORACLE_HOME/rdbms/admin/catldr.sql
Problem is, when I run this script I get multiple errors. E.g. (and there are a lot more than this, stuff about circular synonyms too):
grant select on gv_$loadistat to public
*
ERROR at line 1:
ORA-04063: view "SUKLTI.GV_$LOADISTAT" has errors
create or replace view v_$loadpstat as select * from v$loadpstat
*
ERROR at line 1:
ORA-01731: circular view definition encountered
Synonym created.
grant select on v_$loadpstat to public
*
ERROR at line 1:
ORA-04063: view "SUKLTI.V_$LOADPSTAT" has errors
create or replace view v_$loadistat as select * from v$loadistat
*
ERROR at line 1:
ORA-01731: circular view definition encountered
Synonym created.
grant select on v_$loadistat to public
*
ERROR at line 1:
ORA-04063: view "SUKLTI.V_$LOADISTAT" has errors
from x$kzsro
*
ERROR at line 15:
ORA-00942: table or view does not exist
And then when I try to run SQL*Loader with "direct=true" I receive the following errors:
ORA-26014: unexpected error on column SYS_NTEOzTt73hE9LgU+XYHax0tQ==.DUMMYCOL NAME
while retrieving virtual column status
ORA-01775: looping chain of synonyms
Note this was a clean Oracle install with some XML schema registered(8) and tables generated off the back of the schema.
Any ideas?
The catldr.sql script says:
Rem NAME
Rem catldr.sql
Rem FUNCTION
Rem Views for the direct path of the loader
Rem NOTES
Rem This script must be run while connected as SYS or INTERNAL.
From the error messages you seem to have run it as your normal user, SUKLTI, rather than as SYS. The documentation you linked to also stated it should be run once per database - not once per end-user.
It should have been run during database creation anyway, via the catalog.sql script, so I'm surprised you need to run it manually at all; and some of the errors suggest the objects it creates did already exist. Through re-running it as SYS doesn't really look like it should hurt.
You can see which objects have been created by querying:
select object_type, object_name
from all_objects
where created > time_just_before_you_ran_the_script
You may need to cross-reference public synonyms with the all_synonyms view to check the table owner, and drop any objects it created from the SUKLTI schema as well as those new public synonyms. (But don't drop anything from the SYS schema...)
You may then need to re-run catldr.sql as SYS to recreate those synonyms pointing to the correct SYS objects.
#AlexPoole
You are completely correct. The script had to be run as SYS.
As this was a "test db" we tore it down and ran the script as SYS at DB re-creation time.
Everything now working!
thanks for reply

ORA-01775: looping chain of synonyms

I am creating a table (here below is the code) - this is executed through some script on unix. The script also creates some synonyms (not sure what/how):
drop table BNS_SAA_MESSAGES;
CREATE TABLE BNS_SAA_MESSAGES
(
HostNumber varchar(50) NOT NULL,
SAAMessage varchar(2048) NOT NULL,
PRIMARY KEY (HostNumber)
);
I'm getting the following error:
Processing bns_saa_messages
cat: cannot open bns_saa_messages.sql
Commit complete.
GRANT SELECT ON bns_saa_messages TO RL_ORDFX_RPT
GRANT SELECT ON bns_saa_messages TO RL_ORDFX_RPT
*
ERROR at line 1:
ORA-01775: looping chain of synonyms
GRANT INSERT ON bns_saa_messages TO RL_ORDFX_RPT
GRANT INSERT ON bns_saa_messages TO RL_ORDFX_RPT
*
ERROR at line 1:
ORA-01775: looping chain of synonyms
GRANT UPDATE ON bns_saa_messages TO RL_ORDFX_RPT
GRANT UPDATE ON bns_saa_messages TO RL_ORDFX_RPT
*
ERROR at line 1:
ORA-01775: looping chain of synonyms
GRANT DELETE ON bns_saa_messages TO RL_ORDFX_RPT
GRANT DELETE ON bns_saa_messages TO RL_ORDFX_RPT
*
ERROR at line 1:
ORA-01775: looping chain of synonyms
create public synonym bns_saa_messages for ORDMSO.bns_saa_messages
create public synonym bns_saa_messages for ORDMSO.bns_saa_messages
*
ERROR at line 1:
ORA-00955: name is already used by an existing object
Commit complete.
I googled for ORA-01775: looping chain of synonyms and it seems to mean that a something was removed but there is a pointer to it. I'm guessing it happens during select from 'things' that do not exist anymore. Not sure if these things are tables or something else. This is what I gathered from my research.
Any idea how to create my tables? I tried to execute multiple times the SQL code, but to no avail - I get the same error every time.
Also the table is not created:
SQL> select * from bns_saa_messages;
select * from bns_saa_messages
*
ERROR at line 1:
ORA-01775: looping chain of synonyms
I've looked at the following so questions, but it doesn't seem to be helping. Maybe you can see something I don't:
I get an ORA-01775: looping chain of synonyms error when I use sqlldr
How to debug ORA-01775: looping chain of synonyms?
ORA-01775: looping chain of synonyms but there are no synonyms
Thanks
:UPDATE:
After executing: select * from all_synonyms where synonym_name = 'BNS_SAA_MESSAGES'; as per Craig's suggestion I get:
OWNER SYNONYM_NAME
------------------------------ ------------------------------
TABLE_OWNER TABLE_NAME
------------------------------ ------------------------------
DB_LINK
--------------------------------------------------------------------------------
PUBLIC BNS_SAA_MESSAGES
ORDMSO BNS_SAA_MESSAGES
:UPDATE: 2
Running: select * from all_tables where table_name = 'BNS_SAA_MESSAGES';
SQL> select * from all_tables where table_name = 'BNS_SAA_MESSAGES';
no rows selected
I would run this to see where the synonym is actually pointing:
select *
from all_synonyms
where synonym_name = 'BNS_SAA_MESSAGES'
I am guessing the synonym is pointing to the wrong TABLE_OWNER.
UPDATE
So where is the table actually at? You can find this using:
select *
from all_tables
where table_name = 'BNS_SAA_MESSAGES'
If table_owner is not 'ORDMSO', then you need to either update the synonym to point to the correct location or run the Create table... script as ORDMSO.
UPDATE2
Can you run the Create table... script as ORDMSO? If not, you are going to need to have someone with higher privileges run:
select *
from dba_tables
where table_name = 'BNS_SAA_MESSAGES'
to figure out where the table really is, and then update the synonym accordingly.
It looks like the output is from running this a second time, which you hinted at; the ORA-00955 from the create public synonym shows that has been done before somewhere (as does the all_synonyms query you ran), and it clearly exists from the other errors. You wouldn't have got exactly these errors the first time you ran it, but would on every subsequent run.
At a mimimum the first code snippet should drop the public synonym before dropping the table, if you want it to be rerunnable.
But the first snippet doesn't seem to be run at all. There are no success or failure messages from Oracle. The only real clue to why is this:
Processing bns_saa_messages
cat: cannot open bns_saa_messages.sql
Which is a shell script problem, not really an Oracle one. Without seeing the shell script it's rather hard to tell quite what's wrong, but I suspect the script is building a temporary .sql file from various sources and then running it through SQL*Plus; but the vital bns_saa_messages.sql file is missing. Presumably that's where the first snippet is supposed to be; and since that seems to exist, this could beas simple as a name mismatch between the file and what the script is expecting, or the script is doing a cd and the file is in the wrong directory, or something equally trivial. But maybe not... not enough info.
Are you generating an export?
My solution with a BD oracle 11g was:
See the SYS_EXPORT objects, use Oracle SQL Developer, connect to the DB and execute the following:
Select owner, object_name, object_type, status from dba_objects where object_name like '%SYS_EXPORT%'
Objects SYS_EXPORT
Then with the user: sqlplus / as sysdba removes the created objects.
Delete objects SYS_EXPORT
SQL>drop public synonym sys_export_full_01;
SQL>drop public synonym sys_export_full_02;
SQL>drop public synonym sys_export_full_03;
SQL>drop public synonym sys_export_full_04;
After this you can generate the export.

Resources