Postgresql plpgsql中不寻常的FOR和FOREACH行为

时间:2017-05-26 07:55:36

标签: postgresql for-loop plpgsql

好的,这对某人来说真的很糟糕。在 PostgreSQL 9.4 FUNCTION中发生了一些返回SETOF sometype的眩晕行为。

我已经将(plpgsql)代码简化为它本质上正在做的...

<< myloop >>
FOR items IN SELECT ..... LOOP
  PERFORM pg_notify('debug', 'Step 1');

  IF items.fielda IS NULL THEN
    PERFORM pg_notify('debug', 'Step 1.1');

  ELSE
    PERFORM pg_notify('debug', 'Step 1.2');

    IF something_blah THEN
      PERFORM pg_notify('debug', 'Step 1.2.1');
      -- Used an array her in case of yielding complications, etc.,
      -- but either a FOR IN SELECT or FOREACH produce this same error.
      myarray := returning_sometype_array_function();

      << aloop >>
      FOREACH aitem IN myarray LOOP      -- "aitem" is of "sometype" 
        PERFORM pg_notify('debug', 'Step 1.2.1.x');

        IF aitem.fieldx IS NOT NULL THEN
          -- my array item only produces one record with 
          -- a `fieldx` as NOT NULL.
          id_a := aitem.fieldx;

          RETURN NEXT ROW(...)::sometype;
          PERFORM pg_notify('debug', 'Step 1.2.1.x.1');

        ELSE
          PERFORM pg_notify('debug', 'Step 1.2.1.x.2');
        END IF;

        RETURN NEXT aitem;
        PERFORM pg_notify('debug', 'Step 1.2.1.x finished');
      END LOOP aloop;

      PERFORM pg_notify('debug', 'Step 1.2.1 finished');

    ELSE
      PERFORM pg_notify('debug', 'Step 1.2.2');
      RETURN NEXT ROW(...)::sometype
      PERFORM pg_notify('debug', 'Step 1.2.2 finished');
    END IF;

    PERFORM pg_notify('debug', 'Step 1.2 Finished');
  END IF;

  PERFORM pg_notify('debug', 'Step 1 Finished');
END LOOP myloop;

现在,如果我运行它以便我到达FOREACH循环以进入 Step 1.2.1.x.1 部分,我最终得到以下顺序:通知...

  • 第1步
  • 步骤1.2
  • 步骤1.2.1
  • returning_sometype_array_function()在此处调用
  • 步骤1.2.1.x
  • 步骤1.2.1.x.1
  • 步骤1.2.1.x已完成
  • 再次调用
  • returning_sometype_array_function()
  • 步骤1.2.1.x.2
  • 步骤1.2.1完成
  • 步骤1.2完成
  • 第1步完成
  • 步骤1.2.2

正如您所看到的,似乎我们未执行的ELSE部分(因为它们不符合条件)在它的循环结束时被调用。

此外,returning_sometype_array_function()在调用这些ELSE之前也会再次调用,最终会弄乱我的数据并生成2条记录!此功能仅在该点的代码中出现

我也得到反映这一点的SETOF结果,所以我的代码最终会将两个结果编译成一个,这只会让我的应用程序混淆不清。

此函数用于生成特定项目,具体取决于条件,returning_sometype_array_function()在表中生成一个新的特殊项目,该项目正在重复,因此我的代码会引用第二条记录,我链接到它的其他记录。此功能用于了解是否在通过电线连接更多2个对象时添加连接点。

我似乎无法找到任何有关错误的信息,说实话,不知道怎么问......

有没有人有任何关于错误的经验,或者我没有把事情做对 它编译和流动,我甚至在<< label >>上使用LOOP以防万一,或者可以提供任何建议?

干杯

0 个答案:

没有答案