Oracle plsql ORA-39726 error - oracle

I have my plsql block as below:
DECLARE
CURSOR cdrimei IS select distinct(table_name) as tname from user_tab_columns
where column_name = 'CALLED_NUMBER_TIPO_ABONADO' and table_name not like '%_V' order by table_name;
BEGIN
FOR i in cdrimei
LOOP
execute immediate 'ALTER TABLE '||i.tname||' DROP (IMEI_CHAIN ,IMEI_STOLEN)';
execute immediate 'ALTER TABLE '||i.tname||' ADD (IMEI_CHAIN varchar2(255),IMEI_STOLEN varchar2(255))';
END LOOP;
END;
/
After executing this I am facing the below error:
ORA-39726: unsupported add/drop column operation on compressed tables
I don't understand the meaning of compressed tables.

Compressed tables have some limitations documented in the Administrator's Guide:
The following restrictions apply when adding columns to compressed tables:
Basic compression—You cannot specify a default value for an added column.
OLTP compression—If a default value is specified for an added column, then the column must be NOT NULL. Added nullable columns with default values are not supported.
The following restrictions apply when dropping columns in compressed tables:
Basic compression—Dropping a column is not supported.
OLTP compression—DROP COLUMN is supported, but internally the database sets the column UNUSED to avoid long-running decompression and recompression operations.

Related

How to find the root cause of ORA-54033 error when altering column data type

I am attempting to alter the data type of a column from a NUMBER to a VARCHAR2 in an existing database table. When running the following ALTER TABLE statement I receive the "ORA-54033: column to be modified is used in a virtual column expression" error:
ALTER TABLE table MODIFY (col1 varchar2(8));
I have already worked through the directions listed here. When looking at the SYS generated export statistics using the following query
select column_name, data_default, hidden_column
from user_tab_cols
where table_name = 'Table';
there is nothing referencing col1 in export statistics. There are about 15 hidden, SYS generated rows associated with the table and they all have a data default value of <Long>. There are no virtual columns in the DDL, nor is this column being used for any indexes or as a FK. I have also had the DBA run the following:
SELECT EXTENSION_NAME, EXTENSION, CREATOR, DROPPABLE
FROM DBA_STAT_EXTENSIONS
WHERE TABLE_NAME='Table'
and the output lines up with what I find in user_tab_cols. Where else can I look for this seemingly buried virtual column?

When to specify data length on ALTER TABLE when adding a column

I am writing pl/sql code with dynamic sql statements to ALTER TABLE on table B when new columns are found in table A. When I query all_tab_columns from table a I can return all I need to do this, but in some cases it throws an error when I specify a length for the new column in table B (for example, DATE which I expected). So, I need to parse the results from all_tab_columns to include or exclude a length in the ALTER TABLE statement. On which data types should I leave off a length specification?

How to change lots table columns datatypes from one to another in oracle

I have a table with a lots of columns with BLOB type and I need to change it to nvarchar2.
So, to change type I can use following script:
alter table AUDIT_LOG
modify
(
column_name type_name,
column_name2 type_name2
-- etc
);
And to get all columns with given datatype I can use the following:
select column_name, 'NVARCHAR2(4000)'
from all_tab_columns
where table_name = 'TAB_NAME' and data_type = 'BLOB';
But how to join this two scripts into one?
You cannot do DML and DDL operation together in same query. You have to use dynamic SQL in a PL/SQL block
Create a variable and generate the whole alter table query in it.
Execute Immidiate
Refer this and I am sure you will be able to add rest of the logic as per your requirement.
http://www.java2s.com/Tutorial/Oracle/0440__PL-SQL-Statements/EXECUTEIMMEDIATEdynamicsqltoaltersession.htm

Tsql table variable to Oracle PLSql

I am working on TSql to Plsql conversion.
There are several table variables declared and used in tsql, like
DECLARE #table_var table( id_ int ......)
WHILE ...
begin
insert into #table_var select ...
...
select * from #table_var..
I think in oracle global temporary table can be used, but the data will be maximum 10k rows.
How efficient global temporary tables in this case?
Is there any other way other than global temporary table and table types in Oracle to convert similar sql query?
Oracle version: oracle11g or oracle12c
Depending on your size of the data and task that you want to achieve-- you can use
Pl/sql record/table and bulk processing
hold data in to cursor and loop through it
if you want kind of query update -- you can use in-line view
(preserving primary key)

How to export empty tables in oracle

I have a big problem When i take a dump of database the empty tables are truncated
How i can export the all tables in oracle 10g
exp SYSTEM/password FILE=expdat.dmp
This might be because of these tables may not be extent allocated. Before taking backup you need to identify all the tables that do not have data. Then alter these tables to allocate extent.
ALTER TABLE <table_name> ALLOCATE EXTENT;
Use the below script to alter all tables they do not have extent allocated.
SELECT 'ALTER TABLE '||table_name||' ALLOCATE EXTENT;' FROM user_tables WHERE segment_created = 'NO';
Copy the output and execute it.
You might consider expdp (data pump) instead. There's a parameter CONTENT=METADATA_ONLY that might get you what you want.
I found another solution here.
Oracle has an option called DEFERRED_SEGMENT_CREATION, default true.
from the docs:
If set to true, then segments for tables and their dependent objects (LOBs, indexes) will not be created until the first row is inserted into the table.
I'll sum up the solution from the above link:
SQL> alter system set DEFERRED_SEGMENT_CREATION=FALSE scope=both;
Run the output of the following statement:
SQL> select 'alter table ' || table_name || ' move;' from user_tables where num_rows=0;
This made my exp export empty tables as well.

Resources