2017-07-10 37 views
1

Oracle 11.2.0.4.0を使用し、いくつかのOLTP圧縮テーブルから列を削除しようとすると、ORA-39726: unsupported add/drop column operation on compressed tablesを取得する予定でした。ただし、エラーなしで実行されますが、列は未使用のままですです圧縮テーブルのOracleドロップコラム - 舞台裏で「未使用」に設定

私は、この動作を回避できるかどうか疑問を抱いていました。混乱を避けるために、エラーを取得したいと思います。

私はこれに言及を見つけることができませんでした、私の検索スキルを高める必要があります。私が見るドキュメントでは、

You can set unused a column from a table that uses COMPRESS BASIC, but you cannot drop the column. However, all clauses of the drop_column_clause are valid for tables that use COMPRESS FOR OLTP. See the semantics for table_compression for more information. http://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_3001.htm#i2103683

エラーを発生させるように設定する方法はありますか? シナリオ:

create table test_radu_a(col1 number, col2 number) compress for oltp; 
alter table test_radu_a drop (col2); 
select * from user_unused_col_tabs where table_name = 'TEST_RADU_A'; 

答えて

1

これは予想される動作です。 MOSから文書番号1068820.1:

In 11g it is allowed to drop columns from a compressed table IF compatible is set to 11.1 or higher AND table was created with the "compress for all OLTP" option but even in this situation there is no real drop but internally the database sets the column UNUSED to avoid long-running decompression and recompression operations.

文書1223705.1,2171802.1などを参照してください。実際に列を削除する唯一の方法は、文書1987500.1に示されているように解凍して再圧縮することですが、これは上の引用符で避けていることです。

期待するエラーを得る方法はありません。

私はあなたが得ることができると思う最も近いDDLトリガーである:

create or replace trigger radu_trigger 
before alter 
on schema 
declare 
    l_compress_for user_tables.compress_for%type; 
begin 
    select max(compress_for) into l_compress_for 
    from user_tables 
    where ora_dict_obj_type = 'TABLE' and table_name = ora_dict_obj_name; 

    if l_compress_for is null or l_compress_for != 'OLTP' then 
    return; 
    end if; 

    for r in (
    select column_name from user_tab_columns 
    where table_name = ora_dict_obj_name 
) 
    loop 
    if ora_is_drop_column(r.column_name) then 
     raise_application_error(-20001, 
     'Do not drop columns from an OLTP-compressed table'); 
    end if; 
    end loop; 
end radu_trigger; 
/

その後、あなたはどのOLTP-圧縮テーブルに列を削除しようとすると - そのスキーマに - あなたは、エラーが発生します:

alter table test_radu_a drop (col2); 

alter table test_radu_a drop (col2) 
Error report - 
ORA-00604: error occurred at recursive SQL level 1 
ORA-20001: Do not drop columns from an OLTP-compressed table 
ORA-06512: at line 18 
... 

あなたはもちろん、すべての圧縮されたテーブルをチェックしたくなかった場合は、特定のora_dict_obj_name値を検索できます。


あなたは本当の例外模倣することができます:

create or replace trigger radu_trigger 
before alter 
on schema 
declare 
    l_compress_for user_tables.compress_for%type; 
    l_exception exception; 
    pragma exception_init (l_exception, -39726); 
begin 
... 
    loop 
    if ora_is_drop_column(r.column_name) then 
     raise l_exception; 
    end if; 
    end loop; 
end radu_trigger; 
/

alter table test_radu_a drop (col2); 

Error report - 
ORA-00604: error occurred at recursive SQL level 1 
ORA-39726: unsupported add/drop column operation on compressed tables 
ORA-06512: at line 20 
... 

をそのメッセージが本当に真実ではありませんので、私は、それが混乱すると思います。あなた自身のオーダーメイドの例外を発生させるのは、おそらくより安全でクリーンです。

関連する問題