Oracle SQL Developer flag my working views as broken - sql

Can anyone share me some light on why my Oracle SQL Developer flagged my view as broken while it is actually working?
It is not just 1 view, but 10 views have the same problem, they are all created in a different time, with subquery or joining to multiple tables and is always working fine.
Thanks in advance!

Probably the view was invalidated by a change to a referenced object. Like stored PL/SQL, a recompilation will occur when it is next used, when it will become valid again. For example:
SQL> create table demo (id integer);
Table created
SQL> create or replace view v1 as select id from demo;
View created
SQL> select o.status from user_objects o where object_type = 'VIEW' and object_name = 'V1';
STATUS
-------
VALID
SQL> alter table demo modify id varchar2(10);
Table altered
SQL> select o.status from user_objects o where object_type = 'VIEW' and object_name = 'V1';
STATUS
-------
INVALID
SQL> select * from v1;
ID
----------
SQL> select o.status from user_objects o where object_type = 'VIEW' and object_name = 'V1';
STATUS
-------
VALID

Related

How to set the right to see a view in oracle?

I am logged in as user "a" in my oracle database.
I can write a query like "Select * from MyView" and I get all results - thats fine.
BUT I can't see the view itself in SqlDeveloper in my View-tree (list), additional to that I am not the owner (which I can see with "Select * from all_views").
How can I change the rights of this view to see "MyVIew" in the tree?
#Littlefoot is correct in his answer. You could of course also browse to the view directly via the 'Other Users' portion of the tree, then drill down into the Views.
BUT, you could also just set your Views filter to 'Include Synonyms'
I wrote a story on this topic for TABLES, but it also applies to VIEWS here.
I presume you should query all_objects to see what you're actually dealing with. Why? Because of the following example:
Connected as user mike, I'll create a table, grant select on it to public and create a public synonym:
SQL> connect mike/lion
Connected.
SQL> create table test as select 'Littlefoot' name from dual;
Table created.
SQL> create public synonym myview for test;
Synonym created.
SQL> grant select on test to public;
Grant succeeded.
Connect as another user, scott and select from myview:
SQL> connect scott/tiger
Connected.
SQL> select * from myview;
NAME
----------
Littlefoot
Right; it works. Where is it in SQL Developer?
Aha, it is in public synonyms (I applied filter on name, looking for MYVIEW to skip zillion other public synonyms).
Or, in SQL*Plus:
SQL> select object_name, object_type, owner from all_objects where object_name = 'MYVIEW';
OBJECT_NAME OBJECT_TYPE OWNER
------------------------------ ------------------- ------------------------------
MYVIEW SYNONYM PUBLIC
SQL>
Therefore, I suggest you do the same - query all_objects and you'll know something more about the issue.
you can not change the right of the view to see it your View-tree (list), because it is not your own object. To have the view in your View-tree (list) you have to create it in your own shema.

How to get user/creation date of Trigger in Oracle

Is there any way to get the creation date(time) of the trigger ?
I tried the following query:
select CREATED from user_objects where object_name = '&MY_TRIGGER_NAME'
but i think, i get the last modification/run date, not the creation time.
And also, i want to get the user who created the trigger...if it is possible.
As per the oracle documentation, fields of the USER_OBJECTS is described as:
CREATED: Timestamp for the creation of the object
LAST_DDL_TIME: Timestamp for the last modification of the object resulting from a DDL statement (including grants and revokes)
Let's do one exercise:
Checking in the USER_OBJECTS table for trigger TRG_T
SQL> SELECT OBJECT_NAME,
2 OBJECT_TYPE,
3 CREATED,
4 LAST_DDL_TIME
5 FROM USER_OBJECTS
6 WHERE OBJECT_NAME = 'TRG_T';
no rows selected
Now, Let's create the trigger TRG_T
SQL> CREATE OR REPLACE TRIGGER TRG_T BEFORE
2 INSERT ON T
3 FOR EACH ROW
4 BEGIN
5 NULL;
6 END;
7 /
Trigger created.
Let's check in the USER_OBJECTS
SQL> SELECT OBJECT_NAME,
2 OBJECT_TYPE,
3 CREATED,
4 LAST_DDL_TIME
5 FROM USER_OBJECTS
6 WHERE OBJECT_NAME = 'TRG_T';
OBJECT_NAME OBJECT_TYPE CREATED LAST_DDL_TIME
--------------- --------------- -------------------- --------------------
TRG_T TRIGGER 02-jul-2020 12:41:29 02-jul-2020 12:41:29
Currently, CREATED and LAST_DDL_TIME are the same because the last DDL operation on the trigger is when we created it.
Let's modify the trigger:
SQL> CREATE OR REPLACE TRIGGER TRG_T BEFORE
2 INSERT ON T
3 FOR EACH ROW
4 BEGIN
5 NULL; -- do some changes
6 NULL; -- CHANGED THIS
7 END;
8 /
Trigger created.
Now, let's again check in the USER_OBJECTS:
SQL> SELECT OBJECT_NAME,
2 OBJECT_TYPE,
3 CREATED,
4 LAST_DDL_TIME
5 FROM USER_OBJECTS
6 WHERE OBJECT_NAME = 'TRG_T';
OBJECT_NAME OBJECT_TYPE CREATED LAST_DDL_TIME
--------------- --------------- -------------------- --------------------
TRG_T TRIGGER 02-jul-2020 12:41:29 02-jul-2020 12:42:05
See the CREATED and LAST_DDL_TIME is different here
CREATED is the
timestamp for the creation of the object
in USER_OBJECTS/ALL_OBJECTS/DBA_OBJECTS and not the last modified date which isLAST_DDL_TIME.
To get trigger owner, you need to use OWNER column in ALL_TRIGGERS/DBA_TRIGGERS because USER_TRIGGERS displays only your own triggers without any OWNER column.
there is a field called "created" in user_objects view which tells the creation time of the object. There is another column called last_ddl_time which would show the time of the last creation of the DDL
As for the user who created the object i am not sure its tracked unless you have got a logon trigger that logs this information i believe

How do I invalidate a table in Oracle 11g on purpose?

I'm writing a small query to find invalid tables in Oracle :
select * from user_tables where status != 'VALID'
For testing, I thought it would be good to create a table and invalidate it on purpose. Is there a way to do this?
Invalidating a view is easy, just drop one of the underlying tables.
Any hint welcome.
You won't see status INVALID in user_tables, however, you would see that in [USER|ALL|DBA]_OBJECTS view.
One simple way is to create the table using an object type, and force the object type attribute to invalidate.
For example,
SQL> CREATE OR REPLACE TYPE mytype AS OBJECT(col1 VARCHAR2(10))
2 /
Type created.
SQL>
SQL> CREATE TABLE t(col1 NUMBER,col2 mytype)
2 /
Table created.
SQL>
SQL> SELECT object_name, object_type, status FROM user_objects WHERE object_name='T'
2 /
OBJECT_NAME OBJECT_TYPE STATUS
----------- ----------------------- -----------
T TABLE VALID
SQL>
So, the table is now in VALID status. Let's make it INVALID:
SQL> ALTER TYPE mytype ADD ATTRIBUTE col2 NUMBER INVALIDATE
2 /
Type altered.
SQL>
SQL> SELECT object_name, object_type, status FROM user_objects WHERE object_name='T'
2 /
OBJECT_NAME OBJECT_TYPE STATUS
----------- ----------------------- -----------
T TABLE INVALID
SQL>
Its an old question but I want to point on something for future readers, the opposit of valid in the status user_tables is UNUSABLE so if you want to make a table UNUSABLE,A DROP TABLE operation failed from oracle doc
If a previous DROP TABLE operation failed, indicates whether the table
is unusable (UNUSABLE) or valid (VALID)
As for the type INVALID in user_objects its mainly related to views/package/procedure however lalit kumar gave a good example where a table is invalid.

Find all views that contain a certain table or column

In a legacy database infrastructure, how do I best find views that access a certain table or column? I'm currently refactoring certain tables (i.e. delete unused columns) and I want to find all views that still rely on those columns and will break, if I remove the columns.
Is there any tool/feature to search through all view definitions in Oracle SQL Developer?
You can use something like function dependent_views, code below. Example usage:
select dependent_views('CUSTOMER_NAME', 'CUSTOMERS') list from dual
Output:
LIST
-----------------
SCOTT.V_PERSONS
Function searches dependendent views in ALL_DEPENDENCIES, next searches TEXT column from ALL_VIEWS for occurence of column_name.
Note: Because all_dependences may not contain full data of dependent objects (for instance when view was created by execute immediate) - my function may not find this object.
Also if column_name is substring of other column - function may return to many views.
create or replace function dependent_views
(i_column varchar2, i_table varchar2, i_owner varchar2 default USER)
return varchar2 is
o_ret varchar2(4000) := '';
v_text long := '';
begin
for o in (
select * from all_dependencies
where referenced_name = upper(i_table)
and referenced_owner = upper(i_owner)
and type = 'VIEW')
loop
begin
select text into v_text from all_views
where view_name = o.name and owner = o.owner;
exception when no_data_found then
null;
end;
if upper(v_text) like '%'||upper(i_column)||'%' then
o_ret := o_ret||o.owner||'.'||o.name||' ';
end if;
end loop;
return o_ret;
end dependent_views;
how do I best find views that access a certain table
You could query the [USER|ALL|DBA]_DEPENDENCIES view.
SELECT name ,
type ,
referenced_name ,
referenced_type
FROM user_dependencies
WHERE TYPE = 'VIEW'
AND NAME = '<VIEW_NAME>'
AND referenced_type = '<TABLE_NAME'>;
To get the result for all the views at once, remove the filter NAME = '<VIEW_NAME>'.
For example,
SQL> column name format a15
SQL> column type format a15
SQL> column referenced_name format a15
SQL> column referenced_type format a15
SQL> SELECT name ,
2 type ,
3 referenced_name ,
4 referenced_type
5 FROM user_dependencies
6 WHERE TYPE = 'VIEW';
NAME TYPE REFERENCED_NAME REFERENCED_TYPE
--------------- --------------- --------------- ---------------
EMP_CUSTOM_VIEW VIEW EMP TABLE
EMP_VIEW VIEW EMP TABLE
SQL>
Cause you search for all views that access certain table, this might help:
select
name,
type,
referenced_name,
referenced_type
from user_dependencies
where type = 'VIEW'
and referenced_type = 'TABLE'

How to debug ORA-01775: looping chain of synonyms?

I'm familiar with the issue behind ORA-01775: looping chain of synonyms, but is there any trick to debugging it, or do I just have to "create or replace" my way out of it?
Is there a way to query the schema or whatever to find out what the current definition of a public synonym is?
Even more awesome would be a graphical tool, but at this point, anything would be helpful.
As it turns out, the problem wasn't actually a looping chain of synonyms, but the fact that the synonym was pointing to a view that did not exist.
Oracle apparently errors out as a looping chain in this condition.
If you are using TOAD, go to View>Toad Options>Oracle>General and remove TOAD_PLAN_TABLE from EXPLAIN PLAN section and put PLAN_TABLE
The data dictionary table DBA_SYNONYMS has information about all the synonyms in a database. So you can run the query
SELECT table_owner, table_name, db_link
FROM dba_synonyms
WHERE owner = 'PUBLIC'
AND synonym_name = <<synonym name>>
to see what the public synonym currently points at.
The less intuitive solution to this error code seems to be problems with the objects that the synonym is pointing to.
Here is my SQL for finding synonyms that point to erroneous objects.
SELECT S.OWNER as SYN_OWNER, S.SYNONYM_NAME as SYN_NAME,
S.TABLE_OWNER as OBJ_OWNER, S.TABLE_NAME as OBJ_NAME,
CASE WHEN O.OWNER is null THEN 'MISSING' ELSE O.STATUS END as OBJ_STATUS
FROM DBA_SYNONYMS S
LEFT JOIN DBA_OBJECTS O ON S.TABLE_OWNER = O.OWNER AND S.TABLE_NAME = O.OBJECT_NAME
WHERE O.OWNER is null
OR O.STATUS != 'VALID';
Try this select to find the problematic synonyms, it lists all synonyms that are pointing to an object that does not exist (tables,views,sequences,packages, procedures, functions)
SELECT *
FROM dba_synonyms
WHERE table_owner = 'USER'
AND (
NOT EXISTS (
SELECT *
FROM dba_tables
WHERE dba_synonyms.table_name = dba_tables.TABLE_NAME
)
AND NOT EXISTS (
SELECT *
FROM dba_views
WHERE dba_synonyms.table_name = dba_views.VIEW_NAME
)
AND NOT EXISTS (
SELECT *
FROM dba_sequences
WHERE dba_synonyms.table_name = dba_sequences.sequence_NAME
)
AND NOT EXISTS (
SELECT *
FROM dba_dependencies
WHERE type IN (
'PACKAGE'
,'PROCEDURE'
,'FUNCTION'
)
AND dba_synonyms.table_name = dba_dependencies.NAME
)
)
Today I got this error, and after debugging I figured out that the actual tables were misssing, which I was referring using synonyms. So I suggest - first check that whether the tables exists!! :-))
Step 1) See what Objects exist with the name:
select * from all_objects where object_name = upper('&object_name');
It could be that a Synonym exists but no Table?
Step 2) If that's not the problem, investigate the Synonym:
select * from all_synonyms where synonym_name = upper('&synonym_name');
It could be that an underlying Table or View to that Synonym is missing?
A developer accidentally wrote code that generated and ran the following SQL statement CREATE OR REPLACE PUBLIC SYNONYM "DUAL" FOR "DUAL"; which caused select * from dba_synonyms where table_name = 'DUAL';
to return PUBLIC DUAL SOME_USER DUAL rather than PUBLIC DUAL SYS DUAL.
We were able to fix it (thanks to How to recreate public synonym "DUAL"?) by running
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;
While Jarrod's answer is a good idea, and catches a broader range of related problems, I found this query found in Oracle forums to more directly address the (originally stated) issue:
select owner, synonym_name, connect_by_iscycle CYCLE
from dba_synonyms
where connect_by_iscycle > 0
connect by nocycle prior table_name = synonym_name
and prior table_owner = owner
union
select 'PUBLIC', synonym_name, 1
from dba_synonyms
where owner = 'PUBLIC'
and table_name = synonym_name
and (table_name, table_owner) not in (select object_name, owner from dba_objects
where object_type != 'SYNONYM')
https://community.oracle.com/message/4176300#4176300
You will not have to wade through other kinds of invalid objects. Just those that are actually in endless loops.
I had a similar problem, which turned out to be caused by missing double quotes off the table and schema name.
We had the same ORA-01775 error but in our case, the schema user was missing some 'grant select' on a couple of the public synonyms.
We encountered this error today.
This is how we debugged and fixed it.
Package went to invalid state due to this error ORA-01775.
With the error line number , We went thru the package body code and found the code which was trying to insert data into a table.
We ran below queries to check if the above table and synonym exists.
SELECT * FROM DBA_TABLES WHERE TABLE_NAME = '&TABLE_NAME'; -- No rows returned
SELECT * FROM DBA_SYNONYMS WHERE SYNONYM_NAME = '&SYNONYM_NAME'; -- 1 row returned
With this we concluded that the table needs to be re- created. As the synonym was pointing to a table that did not exist.
DBA team re-created the table and this fixed the issue.
ORA-01775: looping chain of synonyms
I faced the above error while I was trying to compile a Package which was using an object for which synonym was created however underlying object was not available.
I'm using the following sql to find entries in all_synonyms where there is no corresponding object for the object_name (in user_objects):
select *
from all_synonyms
where table_owner = 'SCOTT'
and synonym_name not like '%/%'
and table_name not in (
select object_name from user_objects
where object_type in (
'TABLE', 'VIEW', 'PACKAGE', 'SEQUENCE',
'PROCEDURE', 'FUNCTION', 'TYPE'
)
);
http://ora-01775.ora-code.com/ suggests:
ORA-01775: looping chain of synonyms
Cause: Through a series of CREATE synonym statements, a synonym was defined that referred to itself. For example, the following definitions are circular:
CREATE SYNONYM s1 for s2 CREATE SYNONYM s2 for s3 CREATE SYNONYM s3 for s1
Action: Change one synonym definition so that it applies to a base table or view and retry the operation.
If you are compiling a PROCEDURE, possibly this is referring to a table or view that does not exist as it is created in the same PROCEDURE. In this case the solution is to make the query declared as String eg v_query: = 'insert into table select * from table2 and then execute immediate on v_query;
This is because the compiler does not yet recognize the object and therefore does not find the reference. Greetings.
I had a function defined in the wrong schema and without a public synonym. I.e. my proc was in schema "Dogs" and the function was in schema "Cats". The function didn't have a public synonym on it to allow Dogs to access the cats' function.
For me, the table name and the synonym both existed but under different owner names. I re-created the tables under the owner name that matched the owner name in synonyms.
I used the queries posted by #Mahi_0707