2

(背景: Oracle Warehouse Builder で構築されたデータ ウェアハウスを実行しています。最近、「ORA-02049: ロックを待機中に分散トランザクションのタイムアウト」というエラーが大量に発生するようになりました。並行して ETL ジョブを実行し、これらのジョブのそれぞれがステージング テーブルに対して実行INSERT /*+APPEND PARALLEL*/されます。このステージング テーブルは、ソース システム ID によって分割されます。)

実行時に INSERT のパーティション キーを指定できるかどうかを知りたいです。テーブルがあるとします

create table tmp_loading_table (
  etl_source_system_fk number not null enable,
  object_id number not null enable,
  object_name varchar2(30) not null enable
)
  PARTITION BY LIST ("ETL_SOURCE_SYSTEM_FK") 
 (PARTITION "ESS1"  VALUES (1), 
 PARTITION "ESS2"  VALUES (2)  
);

次に、使用して特定のパーティションに挿入できます

insert  /*+ APPEND PARALLEL("TMP_LOADING_TABLE") */     
into tmp_loading_table partition(ESS1) (
  etl_source_system_fk, object_id, object_name)
(select 1 etl_source_system_fk, object_id, object_name from user_objects);

ただし、これにはパーティション名をハードコーディングする必要があります。

OWB マッピングは汎用的であるため (ソース システム ID をパラメータとして取得する)、実行時に次のようなパーティション名を提供したいと考えています。

insert  /*+ APPEND PARALLEL("TMP_LOADING_TABLE") */     
into tmp_loading_table partition(:partition_name) (
  etl_source_system_fk, object_id, object_name)
(select 1 etl_source_system_fk, object_id, object_name from user_objects);

これは可能ですか?そうでない場合、Oracle Warehouse Builderでこれを実現する別の方法はありますか?

4

1 に答える 1

2

PARTITION FOR構文と動的 SQL が役に立ちます。

理想的には、次のように単純になります。

declare
    v_partition_value number := 1;
begin
    insert  /*+ APPEND PARALLEL("TMP_LOADING_TABLE") */     
    into tmp_loading_table partition for (v_partition_value) (
      etl_source_system_fk, object_id, object_name)
    (select 1 etl_source_system_fk, object_id, object_name from user_objects);
end;
/

残念ながら、上記のコードは で失敗しORA-14108: illegal partition-extended table name syntaxます。それはその構文の明らかな用途のように思えるので、これは奇妙です。

動的 SQL を追加すると、エラーが解消されます。

declare
    v_partition_value number := 1;
begin
    execute immediate '
    insert  /*+ APPEND PARALLEL("TMP_LOADING_TABLE") */     
    into tmp_loading_table partition for ('||v_partition_value||') (
      etl_source_system_fk, object_id, object_name)
    (select 1 etl_source_system_fk, object_id, object_name from user_objects)';
end;
/

私は Oracle Warehouse Builder に精通しておらず、このソリューションがその環境で機能するかどうかもわかりません。また、データ ウェアハウスでは SQL インジェクションは問題にならないと思います。


実行時にパーティション名を指定する別の方法は、システムのパーティション化DATAOBJ_TO_PARTITIONを使用することです。

create table tmp_loading_table (
  etl_source_system_fk number not null enable,
  object_id number not null enable,
  object_name varchar2(30) not null enable
)
PARTITION BY SYSTEM
(
  PARTITION ess1,
  PARTITION ess2
);

declare
    v_object_id number;
begin
    select object_id
    into v_object_id
    from dba_objects
    where object_name = 'TMP_LOADING_TABLE'
        and subobject_name = 'ESS1';

    insert into tmp_loading_table
    partition (dataobj_to_partition (tmp_loading_table, v_object_id))
    values (1, 2, 'A');
end;
/

この方法の大きな欠点は、すべての DML がパーティションを参照する必要があることです。

insert into tmp_loading_table
values (1, 2, 'A');

ORA-14701: partition-extended name or bind variable must be used for DMLs on tables partitioned by the System method

この機能を使っている人は聞いたことがありません。私の経験では、Oracle データ カートリッジにはバグがあります。その動的 SQL は現在どのようになっていますか? :)

于 2013-10-17T04:19:37.840 に答える