Why truncate table does not change the Last DDL Date? - oracle

When I run the following code, I notice that Last DDL Date has not changed.
execute immediate 'truncate table my_table';
What is the problem?
thanks in advance

The truncate table only truncates the table if it is not empty.
If the table is empty then it is not truncated when you execute the truncate table command.
See the demo here:
SQL> select OBJECT_NAME, LAST_DDL_TIME from user_objects where OBJECT_NAME = 'CONTR';
OBJECT_NAME LAST_DDL_TIME
------------ --------------------
CONTR 13-nov-2019 11:45:53
SQL> truncate table CONTR; -- empty table
Table truncated.
SQL> select OBJECT_NAME, LAST_DDL_TIME from user_objects where OBJECT_NAME = 'CONTR';
OBJECT_NAME LAST_DDL_TIME
------------ --------------------
CONTR 13-nov-2019 11:45:53
SQL> INSERT INTO CONTR VALUES (1,1,1,1); -- filling values in the table
1 row created.
SQL> commit;
Commit complete.
SQL> truncate table CONTR;
Table truncated.
SQL> select OBJECT_NAME, LAST_DDL_TIME from user_objects where OBJECT_NAME = 'CONTR';
OBJECT_NAME LAST_DDL_TIME
------------ --------------------
CONTR 13-nov-2019 11:47:46
SQL> -- time is changed now
Cheers!!

I found the answer.
The thing is :
Table is empty.
When a table is empty your truncate ddl does not
change the Last DDL Date.

Related

Does all SP, function must be recompiled, if new column added to the table

One question about ORACLE stored procedures and functions:
I added the new column to the table. This table involve in many stored procedures and functions without using a new column. Do I have to recompile function and procedures, which are using the table, even a new column is not involve in the query of those SP and function? Also do I have to update statistics and so on?
I understand, theoretical question, but anyway.
Please advise.
Thanks
1- if source objects are changed, stored procedures and functions which depend of them must be compile again.
2- If you want to learn which sp or function depends your table, you can try something like;
select * from USER_SOURCE where text like '%your_table_name%';
select * from DBA_SOURCE where text like '%your_table_name%';
select * from ALL_SOURCE where text like '%your_table_name%';
3- You must not collect statics but it will be useful aggregate and update histograms for performance.
It depends on what you change. You can look at the all_dependencies view (or the user_ or dba_ equivalents) to see what may be affected, and the user_objects view to see if something has been made invalid for any reason:
create table t42 (col1 varchar2(10));
insert into t42 (col1) values ('val1');
create procedure p42 as
l_col1 t42.col1%type;
begin
select col1 into l_col1 from t42;
dbms_output.put_line(l_col1);
end p42;
/
column object_name format a12
select object_type, object_name, status
from user_objects
where object_name in ('T42', 'P42');
OBJECT_TYPE OBJECT_NAME STATUS
------------------- ------------ -------
PROCEDURE P42 VALID
TABLE T42 VALID
select type, name, dependency_type
from user_dependencies
where referenced_type = 'TABLE' and referenced_name = 'T42';
TYPE NAME DEPE
------------------ ------------------------------ ----
PROCEDURE P42 HARD
Adding a column doesn't invalidate the procedure in this case:
alter table t42 add (col2 varchar2(10));
select object_type, object_name, status
from user_objects
where object_name in ('T42', 'P42');
OBJECT_TYPE OBJECT_NAME STATUS
------------------- ------------ -------
PROCEDURE P42 VALID
TABLE T42 VALID
Modifying the column used by the procedure does though:
alter table t42 modify (col1 varchar2(20));
select object_type, object_name, status
from user_objects
where object_name in ('T42', 'P42');
OBJECT_TYPE OBJECT_NAME STATUS
------------------- ------------ -------
PROCEDURE P42 INVALID
TABLE T42 VALID
But you don't have to explicitly recompile the procedure; you can if you want to, but Oracle will automatically try to recompile an invalid object when it is referenced:
exec p42;
PL/SQL procedure successfully completed.
select object_type, object_name, status
from user_objects
where object_name in ('T42', 'P42');
OBJECT_TYPE OBJECT_NAME STATUS
------------------- ------------ -------
PROCEDURE P42 VALID
TABLE T42 VALID
You can also use PL/Scope to get more information and details about dependencies too.

Can adding FK or PK constraints invalidate something?

I have a couple of tables with primary-foreign key relations but those constraints do not actually exist. Now I want to add them with an alter table statement.
Will those commands cause any object that depends on the tables to become invalid?
Thanks.
This is a good question. Let's poke the database and see. Here's the set up:
SQL> create table p23 (id number not null, col1 varchar2(10));
Table created.
SQL> create table c23 (id number not null, p_id number not null, col1 varchar2(10));
Table created.
SQL> create or replace procedure tst23
2 is
3 begin
4 insert into p23 values (1, 'ABC');
5 insert into c23 values (11, 1, 'DEF');
6 end;
7 /
Procedure created.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
Everything is copacetic. Now we'll add some constraints.
SQL> alter table p23 add constraint p23_pk primary key (id);
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL> alter table c23 add constraint c23_p23_fk
2 foreign key (p_id) references p23;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
All is still cool. But when we change a table's structure this happens...
SQL> alter table p23 add col2 date;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
INVALID
SQL>
... which is exactly what we would want.
Note that I ran these tests on 11gR2. Oracle introduced fine-grained dependency tracking in 11g, which made programmatic objects more robust when we run DDL on their dependencies. Find out more. So the outcome might be different in earlier versions. It pays to test.
" what is the reason for the procedure to become invalid?"
Structural changes such as adding, modifying or dropping a column potentially have an impact on referencing objects. The procedure had insert statements which didn't specify target columns. So adding a column introduced an ORA-00947: not enough values bug.
But suppose we employed good practice and specified columns?
SQL> create or replace procedure tst23
2 is
3 begin
4 insert into p23 (id, col1) values (1, 'ABC');
5 end;
6 /
Procedure created.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL> alter table p23 add col4 number;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
Now we're protected by fine-grained dependency tracking. Well, sort of. We shouldn't substitute dependency tracking for impact analysis:
SQL> alter table p23 add col5 date not null;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
The procedure has a VALID state but it will still fail when we run it, because it doesn't populate the new mandatory column.

Extra entries in recycle bin when table dropped

I have created a table TESTTABLE28.
Then I dropped the table.DROP TABLE TESTTABLE28;
The show parameter recyclebin; value was set to on.
When I checked the Recycle Bin, observed some other entries along with TESTTABLE28 are listed,
Once I flashback table TESTTABLE28 to before drop; to restore the table, these extra entries are also moved.
What is this values and why it didn't come, when I dropped another table TESTTABLE31 which has only one varchar2 column?
UPDATE
Also how can I restore the constraints which is showing BIN$5lpccCurTNWwCbOSxCK29w==$1 now instead of TESTTABLE28_PK.
Because you have LOB columns in your table you also have segments and indices to them:
SQL> create table t_lb (x int, y clob, z blob);
SQL> col column_name format a10
SQL> col segment_name format a30
SQL> col index_name format a30
SQL> select column_name, segment_name, index_name from user_lobs
2 where table_name = 'T_LB'
3 /
COLUMN_NAM SEGMENT_NAME INDEX_NAME
---------- ------------------------------ ------------------------------
Y SYS_LOB0000701495C00002$$ SYS_IL0000701495C00002$$
Z SYS_LOB0000701495C00003$$ SYS_IL0000701495C00003$$
SQL> show parameter recyclebin
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
recyclebin string ON
SQL> drop table t_lb;
SQL> col object_name format a30
SQL> col type format a30
SQL> select object_name, type from recyclebin
2 /
OBJECT_NAME TYPE
------------------------------ ------------------------------
BIN$8hw9X/AeBmngQ0QTGKxsAQ==$0 TABLE
SYS_LOB0000701495C00003$$ LOB
SYS_LOB0000701495C00002$$ LOB
SYS_IL0000701495C00003$$ LOB INDEX
SYS_IL0000701495C00002$$ LOB INDEX
As of constraint/index restoring - you should rename them back:
SQL> create table t (x int, constraint t_pk primary key(x))
2 /
SQL> drop table t;
SQL> select object_name, type from recyclebin;
OBJECT_NAME TYPE
------------------------------ ------------------------------
BIN$8hw9X/AiBmngQ0QTGKxsAQ==$0 TABLE
BIN$8hw9X/AhBmngQ0QTGKxsAQ==$0 INDEX
SQL> flashback table t to before drop;
SQL> select constraint_name, index_name, constraint_type from
2 user_constraints where table_name = 'T';
CONSTRAINT_NAME INDEX_NAME C
------------------------------ ------------------------------ -
BIN$8hw9X/AgBmngQ0QTGKxsAQ==$0 BIN$8hw9X/AhBmngQ0QTGKxsAQ==$0 P
SQL> begin
2 for cur in (select constraint_name, index_name
3 from user_constraints where table_name = 'T'
4 and constraint_type = 'P') loop
5 execute immediate
6 'alter table t rename constraint "'||cur.constraint_name||
7 '" to t_pk';
8 execute immediate
9 'alter index "'||cur.index_name||'" rename to t_pk';
10 end loop;
11 end;
12 /
SQL> select constraint_name, index_name from user_constraints
2 where table_name = 'T';
CONSTRAINT_NAME INDEX_NAME
------------------------------ ------------------------------
T_PK T_PK

Oracle dropping and recreating synonyms

When we use CTAS like this:
create table big2 as select * from big1;
drop table big1;
rename big2 to big1;
If there are synonym existing on big1, do we need to drop synonym on big1 prior to delete and recreate them? Or is this not necessary?
No. Becuase Synonym is just another name you give to an object ( either within your schema or not). See this code below.
(BTW, shouldn't you rename table t2 to t1 directly?? Does your CTAS have other where conditions, which you are not showing here?)
SQL> create table t1 as
2 select * from scott.emp;
Table created.
SQL> select count(*) from t1;
COUNT(*)
----------
14
SQL> select count(*) from t2;
select count(*) from t2
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> create synonym s1 for t1;
Synonym created.
SQL> create table t2 as
2 select * from t1;
Table created.
SQL> drop table t1;
Table dropped.
SQL> alter table t2 rename to t1;
Table altered.
SQL> select count(*) from t1;
COUNT(*)
----------
14
SQL> select count(*) from s1;
COUNT(*)
----------
14

Does altering or drop-recreating a table in oracle affects the policies defined on it

If i have a table and a defined policy on it then do I need to redefine the policy if I drop and recreate the table or alter it, provided that the alteration or the recreation of the table does not alter elements that the function needs to see?
"do I need to redefine the policy if I
drop and recreate the table"
Yes. Let's create a policy.
SQL> exec dbms_rls.add_policy('APC', 'T23', 'DEPTPOL', 'APC', 'security_policies.get_deptno_predicate')
PL/SQL procedure successfully completed.
SQL> select count(*) from user_policies;
COUNT(*)
----------
1
SQL> exec security_policies.set_deptno(20)
PL/SQL procedure successfully completed.
SQL> select count(*) from t23;
COUNT(*)
----------
6
SQL>
so that works. But if we drop and re-create the table (using a backup I prepared earlier) ...
SQL> drop table t23
2 /
Table dropped.
SQL> create table t23 as select * from t23a
2 /
Table created.
SQL> select count(*) from t23;
COUNT(*)
----------
11
SQL> exec security_policies.set_deptno(20)
PL/SQL procedure successfully completed.
SQL> select count(*) from t23;
COUNT(*)
----------
11
SQL> SQL> select count(*) from user_policies;
COUNT(*)
----------
0
SQL>
"So the question is if I must redefine
the policy even if I will not change
anything in the definition."
No. Providing the change doesn't invalidate the generated predicate altering a table doesn't drop the policy:
SQL> exec dbms_rls.add_policy('APC', 'T23', 'DEPTPOL', 'APC', 'security_policies.get_deptno_predicate')
PL/SQL procedure successfully completed.
SQL> alter table t23 modify deptno number(3,0)
2
SQL> desc t23
Name Null? Type
----------------------------------------- -------- ----------------------------
NAME VARCHAR2(12 CHAR)
ID NUMBER
AGE NUMBER(4)
DEPTNO NUMBER(2)
SQL> alter table t23 modify deptno number(3,0)
2 /
Table altered.
SQL> exec security_policies.set_deptno(20)
PL/SQL procedure successfully completed.
SQL> select count(*) from t23;
COUNT(*)
----------
6
SQL>
Note that the change modified the column which is tested by the predicate and the policy still remains in force.
"does a 'CREATE OR REPLACE VIEW'
statement drops and recreates it or
does it alter it?"
Let's try it:
SQL> create view v23 as select * from t23;
View created.
SQL> exec dbms_rls.add_policy('APC', 'V23', 'DEPTPOLV', 'APC', 'security_policies.get_deptno_predicate')
PL/SQL procedure successfully completed.
SQL> exec security_policies.set_deptno(10)
PL/SQL procedure successfully completed.
SQL> select count(*) from v23;
COUNT(*)
----------
5
SQL> create or replace view v23 as select name, age from t23;
View created.
SQL> select count(*) from v23;
select count(*) from v23
*
ERROR at line 1:
ORA-28113: policy predicate has error
SQL>
Okay, so that's an error because the view's new projection doesn't include the column in the predicate. But it suggests teh ploicy is still in place. So let's fix that error:
SQL> create or replace view v23 as select name, age, deptno from t23;
View created.
SQL> select count(*) from v23;
COUNT(*)
----------
5
SQL>

Resources