WITH语句中的FOR循环

时间:2016-02-03 13:46:56

标签: sql oracle oracle11g

我创建了一个WITH语句,例如:

 WITH data AS(
   SELECT COUNT (*) as a, E.b as b
   FROM         table1 C
   JOIN         table2 D
   ON           D.MY_ID = C.MY_ID
   JOIN         table3 E
   ON           E.NEW_ID = C.NEW_ID
   WHERE        E.b BETWEEN 1 AND 4
   GROUP BY     E.b
   ORDER BY     E.b)

我想在这样的for循环中使用它:

BEGIN
FOR x IN 1..100 LOOP
{ WITH data AS(
       SELECT COUNT (*) as a, E.b as b
       FROM         table1 C
       JOIN         table2 D
       ON           D.MY_ID = C.MY_ID
       JOIN         table3 E
       ON           E.NEW_ID = C.NEW_ID
       WHERE        E.b BETWEEN 1 AND 4
       GROUP BY     E.b
       ORDER BY     E.b)}
END LOOP;
END;

但是oracle说我需要在这个声明中。我该怎么办?我应该使用光标吗?它看起来怎么样?

2 个答案:

答案 0 :(得分:3)

鉴于您只需要运行相同查询的100次,请考虑一下,无论您是否使用INTO,都必须使用WITH子句。

您可以尝试这种方式:

DECLARE
    type tab_number is table of number;
    vA tab_number;
    vB tab_number;
BEGIN
    FOR I IN 1 .. 100 LOOP
       WITH data AS(
           SELECT COUNT (*) as a, E.b as b
           FROM         table1 C
           JOIN         table2 D
           ON           D.MY_ID = C.MY_ID
           JOIN         table3 E
           ON           E.NEW_ID = C.NEW_ID
           WHERE        E.b BETWEEN 1 AND 4
           GROUP BY     E.b
           ORDER BY     E.b
       )
       SELECT A, B
       BULK COLLECT INTO vA, vB
       FROM DATA;
   END LOOP;
END;

甚至没有WITH

DECLARE
    type tab_number is table of number;
    vA tab_number;
    vB tab_number;
BEGIN
    FOR I IN 1 .. 100 LOOP
       SELECT COUNT (*) as a, E.b as b
       BULK COLLECT INTO vA, vB
       FROM         table1 C
       JOIN         table2 D
       ON           D.MY_ID = C.MY_ID
       JOIN         table3 E
       ON           E.NEW_ID = C.NEW_ID
       WHERE        E.b BETWEEN 1 AND 4
       GROUP BY     E.b
       ORDER BY     E.b;
   END LOOP;
END;

请注意,在这些示例中,我们使用BULK COLLECT,因为您的查询可能会返回多行。 如果您只需要一行,则可以删除GROUP BY子句并尝试以下内容:

DECLARE
    vA NUMBER;
BEGIN
    FOR I IN 1 .. 100 LOOP
       SELECT COUNT (*) as A
       INTO vA
       FROM         table1 C
       JOIN         table2 D
       ON           D.MY_ID = C.MY_ID
       JOIN         table3 E
       ON           E.NEW_ID = C.NEW_ID
       WHERE        E.b BETWEEN 1 AND 4;
   END LOOP;
END;

请注意,这可能不是检查查询性能的最佳方法:首次运行后,数据可能已经被缓存,因此以下运行可能会更快

答案 1 :(得分:2)

  

我需要检查此声明的运行时间

您假设WITH部分独立于使用的实际查询运行,这通常是不正确的。 WITH将与使用它的部分一起编译成一个执行计划。如果你想单独检查WITH部分,那么只需取出WITH行并在其中运行`SELECT。

但是,运行整个查询或获得更好的SQL分析工具会更准确。