2

(背景:我們正在運行使用Oracle Warehouse Builder構建的數據倉庫最近,我們開始在等待鎖定時獲得大量「ORA-02049:分佈式事務超時「錯誤,原因是我們並行運行多個ETL作業,並且這些作業中的每一個都將INSERT /*+APPEND PARALLEL*/插入到暫存表中。該暫存表由源系統ID進行分區。)Oracle/OWB:在運行時指定用於INSERT的分區

I' d想知道是否可以在運行時指定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實現這一點?

回答

1

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注入不是問題。


另一種方式在運行時指定分區名稱是system partitioningDATAOBJ_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現在看起來如何? :)

+0

感謝您的答案 - 我只想使用動態SQL作爲最後的手段,因爲這將使OWB思路更復雜。令人遺憾的是PARTITION FOR語法不起作用:-( –