2014-01-13 5 views
2

Мне нужно иметь дело с тремя таблицами с геометриями.Несколько курсоров в одном заявлении

DECLARE 
    CURSOR c1 IS 
    SELECT 
     store_number, 
     0 AS total_area, 
     0 AS bg_id, 
     0 AS store_geom 
    FROM table1 WHERE client_id = 1 AND org_id = 1; 

    TYPE c1_tab_type IS TABLE OF c1%ROWTYPE; 
    c1_list c1_tab_type; 

BEGIN 

    FOR r1 IN c1 
    LOOP 

    SELECT bg_id, store_number, total_area 
    BULK COLLECT INTO c1_list 
    FROM (
     SELECT 
      bg_id, 
      store_number, 
      b.geometry              store_geom, 
      ((sdo_geom.SDO_AREA(sdo_geom.SDO_INTERSECTION(a.geometry, b.geometry, 0.005), 0.005, 'unit=sq_mile')/
      sdo_geom.SDO_AREA((a.geometry), 0.005, 'unit=sq_mile')) * 100) total_area 
     FROM table2 a, table1 b 
     WHERE store_number != r1.store_number 
       AND sdo_relate(a.geometry, b.geometry, 'mask=anyinteract') = 'TRUE'); 

    IF total_area = 100 THEN 
     FOR i IN 1..c1_list.count LOOP 
     INSERT INTO temp_prop_area_100 VALUES c1_list(i); 
     END LOOP; 
    ELSE IF 
     FOR i IN 1..c1_list.count LOOP 
     INSERT INTO temp_Prop_area_block VALUES c1_list(i); 
     END LOOP; 
    END IF; 

    END LOOP; 
END; 

Так что выбрать запись (самую большую геометрию всех три таблиц) из таблицы 1 и наложения более мелкие полигоны из таблицы 2. я получаю список перекрывающихся геометрии из таблицы 2. Это может иметь несколько из них пересекаются, а некоторые из них полностью находятся под полигоном из таблицы 1.

Затем я хочу разместить их в двух разных таблицах. Те, которые полностью находятся в temp_prop_area и те, которые пересекаются в temp_prop_area_block.

Теперь проблема заключается в том, что когда я получаю идентификатор для всех пересекающихся полигонов (temp_prop_area_block), я хочу наложить каждый из этого многоугольника на многоугольники из таблицы 3, в области меньших полигонов. И аналогичным образом выясните, какие полигоны они интуитивно понятны и какова область пересечения.

Размер многоугольника в этом порядке полигонах из таблицы 1, как самые большие, то из таблицы 2 или temp_prop_area_block и затем многоугольников из таблицы 3.

ответ

2

У вас есть несколько вариантов. total_area не существует вне типа записи вы определили, так что вы не можете использовать его в if, где вы показали, но вы можете просто настроить, что немного:

... 
        For i in 1..c1_list.count loop 
         if c1_list(i).total_area=100 
          then     
          insert into temp_Prop_area_100 
          values c1_list(i); 
         else 
          insert into temp_Prop_area_block 
          values c1_list(i); 
         end if; 
        End Loop; 
      End Loop; 
End; 

Или вы можете разделить ваш перечислить на два:

Type C1_TAB_TYPE is table of c1%ROWTYPE;  
    c1_list c1_TAB_TYPE; 
    c1_list_100 c1_TAB_TYPE; 
    c1_list_block c1_TAB_TYPE; 
... 
        For i in 1..c1_list.count loop 
         if c1_list(i).total_area=100 
          then     
          c1_list_100.extend(); 
          c1_list_100(c1_list_100.last) := c1_list(i); 
         else 
          c1_list_block.extend(); 
          c1_list_block(c1_list_block.last) := c1_list(i); 
         end if; 
        End Loop; 

        For i in 1..c1_list_100.count loop 
         insert into temp_Prop_area_100 
         values c1_list_100(i); 
        End Loop; 
        For i in 1..c1_list_block.count loop 
         insert into temp_Prop_area_block 
         values c1_list_block(i); 
        End Loop; 
      End Loop; 
End; 

который выглядит как его добавление дополнительной сложности за не большой доход, который может быть правдой, если вы будете продолжать использовать отдельные вставки. Но это также позволяет использовать forall синтаксис, упомянутый в a previous answer:

Type C1_TAB_TYPE is table of temp_prop_area%ROWTYPE;  
... 
        Forall i in 1..c1_list_100.count 
         insert into temp_Prop_area_100 
         values c1_list_100(i); 
        Forall i in 1..c1_list_block.count 
         insert into temp_Prop_area_block 
         values c1_list_block(i); 
      End Loop; 
End; 

Вы также можете сделать отдельные select ... bulk collect заявления в двух списках, с различными фильтрами, но включает в себя удары таблицы дважды, и, вероятно, будет меньше эффективный.

Смежные вопросы