Sql Oracle/OWB:指定运行时插入的分区

Sql Oracle/OWB:指定运行时插入的分区,sql,oracle,plsql,database-partitioning,oracle-warehouse-builder,Sql,Oracle,Plsql,Database Partitioning,Oracle Warehouse Builder,(背景:我们正在运行一个使用Oracle warehouse Builder构建的数据仓库。最近,我们开始收到很多“ORA-02049:等待锁定时的分布式事务超时”的消息错误。这是因为我们并行运行多个ETL作业,并且每个作业都将INSERT/*+APPEND parallel*/插入到暂存表中。此暂存表按源系统ID进行分区。) 我想知道是否可以在运行时为INSERT指定分区键。 假设我有一张桌子 create table tmp_loading_table ( etl_source_syst

(背景:我们正在运行一个使用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实现这一点?

语法和动态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:非法分区扩展表名语法时失败
。这很奇怪,因为这似乎是一个明显的用途 对于该语法

添加动态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注入不是一个问题


在运行时指定分区名称的另一种方法是 和

此方法的巨大缺点是每个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现在看起来怎么样?:)

感谢您的回答-我只想使用动态SQL作为最后手段,因为这将使OWB方式的思考更加复杂。很遗憾,语法分区不起作用:-(
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