2014-01-13 48 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中相交的節點。

現在我遇到的問題是,當我得到所有相交多邊形的id(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; 

,它看起來像它增加了額外的複雜性沒有多大的收穫,如果你繼續使用個別插入這也許是真實的。但是,這也可以讓你使用a previous answer提到的forall語法:

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語句到兩個列表,有不同的過濾器,但涉及打兩次表,並有可能要少高效。