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
Related
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
How to prevent a user from not dropping a view even he/she has previlige to do so? I have a view being used by an application. However, it was dropped by a user a couple times. Is there something like REVOKE DROP ANY VIEW? Do I have to use a trigger for that?
A trigger might help. Here's an example.
First, a few objects to be dropped:
SQL> create table test as select * From emp where 1 = 2;
Table created.
SQL> create or replace view v_dept as select * From dept;
View created.
SQL>
I don't want to allow V_DEPT to be dropped, so:
SQL> create or replace trigger trg_drop
2 before drop on schema
3 declare
4 l_name varchar2(30);
5 begin
6 select ora_dict_obj_name
7 into l_name
8 from dual;
9 if l_name = 'V_DEPT' then
10 raise_application_error(-20001, 'Forbidden');
11 end if;
12 end;
13 /
Trigger created.
Testing:
SQL> drop view v_dept;
drop view v_dept
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Forbidden
ORA-06512: at line 8
SQL> drop table test;
Table dropped.
SQL>
I have created a sequence plsql_profile_runnumber in sys user, but I cannot find it in dba_objects or dba_sequences. Please find the executiion details:
SQL> create sequence plsql_profiler_runnumber start with 1 nocache;
Sequence created.
SQL> select * from sys.dba_objects where object_name ='PLSQL_PROFILE_RUNNUMBER';
no rows selected
SQL> grant select on plsql_profile_runnumber to vps_user;
grant select on plsql_profile_runnumber to vps_user
*
ERROR at line 1:
ORA-00942: table or view does not exist
create sequence plsql_profiler_runnumber start with 1 nocache;
select * from sys.dba_objects where object_name ='PLSQL_PROFILE_RUNNUMBER';
Answer: The sequence you created was PLSQL_PROFILER_RUNNUMBER.
The object name you reference was PLSQL_PROFILE_RUNNUMBER.
The two names are different. PROFILER vs. PROFILE.
PLSQL_PROFILE_RUNNUMBER
and
plsql_profiler_runnumber
are different by
ending r of profiler.
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.
I have an oralcle SP forced on me that will not accept an empty parameter in an update. So if I wanted to set a value back to the default of ('') it will not let me pass in the empty string. Is there a keyword you can use such as default, null, etc that oracle would interpret back to the default specified for a particular column?
Sometimes things are just as simple as you hope they might be.
First, a table with a default value ...
SQL> create table t23 (
2 id number not null primary key
3 , col_d date default sysdate not null )
4 /
Table created.
SQL> insert into t23 values (1, trunc(sysdate, 'yyyy'))
2 /
1 row created.
SQL> select * from t23
2 /
ID COL_D
---------- ---------
1 01-JAN-10
SQL>
Next a procedure which updates the default column ...
SQL> create or replace procedure set_t23_date
2 ( p_id in t23.id%type
3 , p_date in t23.col_d%type )
4 is
5 begin
6 update t23
7 set col_d = p_date
8 where id = p_id;
9 end;
10 /
Procedure created.
SQL>
... but which doesn't work as we would like:
SQL> exec set_t23_date ( 1, null )
BEGIN set_t23_date ( 1, null ); END;
*
ERROR at line 1:
ORA-01407: cannot update ("APC"."T23"."COL_D") to NULL
ORA-06512: at "APC.SET_T23_DATE", line 6
ORA-06512: at line 1
SQL>
So, let's try adding a DEFAULT option ...
SQL> create or replace procedure set_t23_date
2 ( p_id in t23.id%type
3 , p_date in t23.col_d%type )
4 is
5 begin
6 if p_date is not null then
7 update t23
8 set col_d = p_date
9 where id = p_id;
10 else
11 update t23
12 set col_d = default
13 where id = p_id;
14 end if;
15 end;
16 /
Procedure created.
SQL>
... and lo!
SQL> exec set_t23_date ( 1, null )
PL/SQL procedure successfully completed.
SQL>
SQL> select * from t23
2 /
ID COL_D
---------- ---------
1 28-FEB-10
SQL>
I ran this example on an 11g database. I can't remember when Oracle introduced this exact support for DEFAULT, but it has been quite a while (9i???)
edit
The comments are really depressing. The entire point of building PL/SQL APIs is to make it easier for application developers to interact with the database. That includes being sensible enough to rewrite stored procedures when necessary. The big difference between building something out of software and, say, welding cast-iron girders together is that software is malleable and easy to change. Especially when the change doesn't alter the signature or behaviour of an existing procedure, which is the case here.
The procedure that's been forced on you:
create or replace procedure notEditable(varchar2 bar) as
begin
--update statement
null;
end;
How to use:
begin
notEditable(bar=>null);
end;
I didn't actually compile, but I believe this is the correct syntax.