ForALL构造:集合范围可以初始化为常量吗?

时间:2018-06-15 08:09:23

标签: sql oracle plsql forall

我想在程序中使用ForAll构造:

现有的For循环是:

      max_versions constant number := 100;
      FOR i IN 1 ..max_vers 
        LOOP
           l_sql := 'update test_table set p' || i ||'= NULL WHERE p' ||i||'=0 AND           condition1=' ||n_input1 ||' AND  condition3 = ' || n_condition3;
         EXECUTE immediate l_sql;

           l_sql := 'update test_table set h' || i ||'= NULL WHERE h ||i||'=0 AND                condition1=' ||n_input1 ||' AND  condition3 = ' || n_condition3;
         EXECUTE immediate l_sql;
        END LOOP;

这里max_vers是常数100,p1 ... p100和h1 ... h100是表格中的列。在上面的查询中,如果列为'值为0.

那么可以使用常量而不是集合来使用ForAll吗?

我尝试过以下操作: 首先,我尝试使用直接常数' Count'方法,但因为它是一种收集方法

PROCEDURE Test
IS 

TYPE MaxVersTab IS TABLE OF number;
maxvers MaxVersTab := 100; 
                             -- Error1
BEGIN

    FORALL i IN 1 .. maxvers .count
    EXECUTE IMMEDIATE -- Error2 and Error3
    'update test_table set p' || i ||'= NULL WHERE p' ||i||'=0 AND condition1=' ||n_input1 || ' AND condition3 =n_input3' USING maxvers(i);

    FORALL i IN 1 ..  maxversions.count
    EXECUTE IMMEDIATE
    'update test_table set p' || i ||'= NULL WHERE p' ||i||'=0 AND condition1=' ||n_input1 || ' AND condition3=n_input3'  USING maxvers(i);

我得到的错误如下:

  • 错误1)表达式类型错误
  • 错误2)语句被忽略
  • 错误3)此表达式类型的声明不完整

我的问题是,我们可以为ForAll中使用的集合(如100)指定一个范围。请告诉我。

此致

3 个答案:

答案 0 :(得分:1)

不,你不能在这里使用FORALL。

  

FORALL语句多次运行一个DML语句   VALUES和WHERE子句中的不同值。

您处理不同的DML语句,而不是唯一的语句。 您的DML语句不同,因为您在其中使用了不同的列。

如果你有一个DML声明,你可以这样做:

declare
  TYPE MaxVersTab IS TABLE OF number;
  maxvers MaxVersTab; 
  n_input1 varchar2(32767) := 'some_condition_string';
BEGIN
  select level
  bulk collect into maxvers
  from dual
  connect by level <= 5;

  FORALL i IN 1 .. maxvers .count
    EXECUTE IMMEDIATE
      'update test_table set p1 = null WHERE p1=:bind_variable1 AND condition1=:bind_variable2' using maxvers(i), n_input1;
end;

答案 1 :(得分:0)

只是为了确认您无法使用forall

您无法自行调用forall机制作为生成器:

begin
    forall i in 1..100
        insert into demo(id) values (i);
end;

失败了:

ORA-06550: line 3, column 38:
PLS-00430: FORALL iteration variable I is not allowed in this context
ORA-06550: line 3, column 9:
PLS-00435: DML statement without BULK In-BIND cannot be used inside FORALL

您必须实际使用该集合。

要设置100个元素的集合,您必须extend它(因此它不能是常量,除非我们编写一个函数来初始化它)。以下运行,但它插入空值,因为我们没有生成任何值:

declare 
    type number_tt is table of number;
    numbers number_tt := number_tt();
begin
    numbers.extend(100);

    forall i in 1..100
        insert into demo(id) values (numbers(i));
end;

您可以从select(或其他一些方法)填充集合,但我们现在正在逐渐采用快速方法来使用100个值来填充forall,以便我们可以使用它执行100次任务。

declare 
    type number_tt is table of number;
    numbers number_tt := number_tt();
begin
    select rownum bulk collect into numbers
    from dual connect by rownum <= 100;

    forall i in 1..100
        insert into demo(id) values (numbers(i));
end;

答案 2 :(得分:0)

不是使用For循环,而是使用静态查询,该查询将一次性更新h1..h100和p1 ... p100列。

const enum YourEnumType {
    None = 0,
    OneThing = 1,
    OtherThing = 2
}
export {YourEnumType};

这会将查询执行次数从200减少到

致谢