1. 程式人生 > >oracle 遊標使用的一個例子

oracle 遊標使用的一個例子

這裡用的市plsql 處理oracle 資料庫的大量資料,因為之前也沒怎麼用過,也就自己瞎摸索這弄弄看,業務需求,如果有什麼不妥的地方還請指正

這裡有個需求是這樣的 一張型別表 T_DEMO_TYPE 

一張  資訊表 demo_handel_1 

表結構如下:

create table T_DEMO_TYPE
(
  id       NUMBER,
  parentid NUMBER,
  name     VARCHAR2(100),
  leaf     NUMBER
)

create table DEMO_HANDEL_1
(
  id            NUMBER,
  companyname   VARCHAR2(100),
  province      VARCHAR2(50),
  city          VARCHAR2(50),
  createdate    VARCHAR2(50),
  registerfund  VARCHAR2(50),
  areaname      VARCHAR2(200),
  busi_name     VARCHAR2(4000),
  busi_typename VARCHAR2(560),
  busi_id       VARCHAR2(500),
  busitype_id   VARCHAR2(500),
  citycode      VARCHAR2(10)
)

說白了就是需要將 busi_name 這個欄位的值 像 “aa,bb,cc,dd”  這樣的字串轉換成 與他們對應的 id 的 “1,3,2,6” 

create or replace procedure pro_demo_test
as 
    cursor c_project_cursor is select t.id,t.busi_name from demo_handel_1 t;
    cursor c_busi_type_cursor is select t.id,t.name from T_DEMO_TYPE t;
    v_busi_id   T_DEMO_TYPE.id%type;
    v_busi_type T_DEMO_TYPE.name%type;
    v_busi_name demo_handel_1.busi_name%type;
    v_id        demo_handel_1.id%type;
    v_temp      varchar2(2000);
    v_count     number default 0;
    v_temp_ids varchar(2000);
begin
  open c_project_cursor;
  fetch c_project_cursor into v_id,v_busi_name;
  while c_project_cursor%found loop
     --  dbms_output.put_line('v_busi_name:'||v_busi_name);
            v_temp_ids:=null;
             ---字串處理 包含逗號個數--
             v_count:= nvl(LENGTH(REGEXP_REPLACE(REPLACE(v_busi_name,',','@'),'[^@]+','')),0)+1;
               -------包含逗號-------
               while v_count>0 loop
                       if v_count>1 then
                           ---當前項
                           v_temp:=substr(v_busi_name,0,instr(v_busi_name,',')-1);
                        else
                              v_temp:=v_busi_name;
                       end if;
                         ----擷取當前項後剩餘
                         v_busi_name:=substr(v_busi_name,instr(v_busi_name,',')+1); 
                           
                                ----讀取型別表 匹配當前項
                                open c_busi_type_cursor;
                                fetch c_busi_type_cursor into v_busi_id,v_busi_type;
                                while c_busi_type_cursor%found loop 
                                       if  v_temp=v_busi_type then
                                          --dbms_output.put_line('v_busi_id:'||v_busi_id);
                                         --拼接id
                                        v_temp_ids:=concat(v_temp_ids,v_busi_id||','); 
                                         end if; 
                                      fetch c_busi_type_cursor into v_busi_id,v_busi_type;
                                end loop;
                                close c_busi_type_cursor;
                       --  dbms_output.put_line('v_temp:'||v_temp);
                       --  dbms_output.put_line('v_count:'||v_count);
                       
                        v_count:=v_count-1;
                       end loop;
             update demo_handel_1 t set t.busi_id=substr(v_temp_ids,0,length(v_temp_ids)-1) where t.id=v_id;
              --dbms_output.put_line('v_temp_ids:'||v_temp_ids);
             fetch c_project_cursor into v_id,v_busi_name;
     end loop;
  close c_project_cursor;
end;

call pro_demo_test();

後面又碰到一個更麻煩的但是也類似這種的要從一串地址中抽取  省 市的資訊.

 但是問題是這些地址中很多資訊不全 就很麻煩因為確定一個市有時候至少需要明確省市縣中兩個.有的甚至只是一個街道名而已,索性這樣的資料是少數大概佔五分之一多點 先處理能處理的吧那就 

/**********根據地址拆分出省市***************/
create or replace procedure pro_demo_province_city
as 
    --cursor c_project_cursor is select t.id,t.areaname from temp_city t where rownum<50 ;where t.id=1142 where t.id=584
    cursor c_project_cursor is select t.id,t.areaname,t.province from temp_city t ;
    cursor c_city_cursor is select t.id,t.cityname,t.citycode,t.parentcode,t.leaf from T_CITY_MODEL t;
    cursor c_city_byname(v_name varchar) is select cityname,citycode,parentcode,leaf from T_CITY_MODEL where cityname=v_name;
    cursor c_county_byname(v_name varchar) is select cityname,citycode,parentcode,leaf from T_CITY_MODEL where cityname=v_name and leaf=2;
    
    v_city_id                      T_CITY_MODEL.id%type;
    v_city_name                    T_CITY_MODEL.cityname%type;
    v_city_code                    T_CITY_MODEL.citycode%type;
    v_city_parent_code             T_CITY_MODEL.parentcode%type;
    
    
    v_county_name                    T_CITY_MODEL.cityname%type;
    v_county_code                    T_CITY_MODEL.citycode%type;
    v_county_parent_code             T_CITY_MODEL.parentcode%type;
 
    v_leaf                         T_CITY_MODEL.leaf%type;
    v_areaname                     temp_city.areaname%type;
    v_provinceName                 temp_city.province%type;
    v_id                           temp_city.id%type;          
    v_temp                         varchar2(2000);
    v_count                        number default 0;
    v_temp_ids                     varchar(2000);
    v_province                     varchar(100);
    v_city                         varchar(100);
    v_county                       varchar(100);
    v_province_index               number;  
    v_city_index                   number;  
    v_county_index                 number;  
    v_temp_index                   number;
    v_flag                        number;
    
     some_kinds_of_err EXCEPTION;  -- Exception to indicate an error condition   
      v_ErrorCode NUMBER;           -- Variable to hold the error message code  
      v_ErrorText VARCHAR2(200);    -- Variable to hold the error message text  
     
    
begin
  open c_project_cursor;
  fetch c_project_cursor into v_id,v_areaname,v_provinceName;
     
  while c_project_cursor%found loop
               v_city:='';
               v_county:='';   
               v_province_index:=instr(v_areaname,'省'); 
               v_city_index:=instr(v_areaname,'市');
               v_county_index:=instr(v_areaname,'縣');
               v_flag:=v_county_index-v_city_index;


              if(v_city_index>0 and v_province_index>0 and v_county_index>0) then  ---省市縣存在
                       v_province:=substr(v_areaname,0,v_province_index-1);
                       v_areaname:=substr(v_areaname,v_province_index+1);    
                       v_temp_index:=instr(v_areaname,'市');
                       v_city:=substr(v_areaname,0,v_temp_index-1);            
                       v_areaname:=substr(v_areaname,v_temp_index+1);
                       v_temp_index:=instr(v_areaname,'縣');
                       v_county:=substr(v_areaname,0,v_temp_index-1);
                       if(length(v_county)=1)then
                         v_county:=v_county||'縣';
                         end if;
                 --  dbms_output.put_line('省:>>>'||v_province||'---市:>>>>'||v_temp||'---縣:>>>>'||v_county); 
                  end if;
                  
                                                       
                 if(v_city_index>0 and v_county_index>0 and v_province_index =0 and v_flag>0) then  ---市縣存在 長治市平順縣青羊鎮大渠村
                               
                      v_city:=substr(v_areaname,0,v_city_index-1);
                      v_temp_index:=instr(v_areaname,'縣');
                      v_county:=substr(v_areaname,v_city_index+1,v_temp_index-v_city_index);
                      if(length(v_county)=1)then
                         v_county:=v_county||'縣';
                         end if;
                   --  dbms_output.put_line('---市>>>>'||v_city||'---縣>>>>'||v_county); 
                  end if;
                     
                                                        
                   if((v_city_index=0 and v_province_index=0 and v_county_index>0 )or (v_city_index>0 and v_county_index>0 and v_province_index =0 and v_flag<0)) then ---只有縣存在
                   
                     
                       v_temp_index:=instr(v_areaname,'縣');
                       v_county:=substr(v_areaname,0,v_temp_index-1);
                       if(length(v_county)=1)then
                         v_county:=v_county||'縣';
                         end if;
                       --   dbms_output.put_line('--只有縣----------'||v_county); 
                          --dbms_output.put_line(v_provinceName);
                         begin
    
                             select citycode into v_city_parent_code from T_CITY_MODEL t where t.cityname like '%'||v_provinceName||'%' and leaf =0;--省id
                            -- dbms_output.put_line(v_city_parent_code); 
                              select parentcode into v_city_code from T_CITY_MODEL t where t.cityname =v_county and leaf=2 and t.citycode like '%'||substr(v_city_parent_code,0,2)||'%';---市id
                            -- dbms_output.put_line(v_provinceName||'----'||v_county||'----'||v_city_code||'----------'||v_city_parent_code);
                             select citycode,cityname into v_city_code,v_city_name from T_CITY_MODEL where citycode=v_city_code and parentcode = v_city_parent_code;
                              exception 
                                    when no_data_found then 
                                    v_city_code :='null';          
                                    v_city_name :='null';
                                    v_city_parent_code :='null';
                              end;
                              
                             update  temp_city t set t.city=v_city_name,t.citycode=v_city_code where t.id=v_id;
                             
                             commit; 
                              -- dbms_output.put_line('省>>>'||v_province||'---市>>>>'||v_temp||'---縣>>>>'||v_county);
                           
                    end if;
                    
                     
                         
                  if(v_province_index>0 and v_city_index>0 and v_county_index=0 ) then ---省市都存在 (同省市縣都存在的情況)
                        v_province:=substr(v_areaname,0,v_province_index-1);
                        v_areaname:=substr(v_areaname,v_province_index+1);
                        v_temp_index:=instr(v_areaname,'市');
                        v_city:=substr(v_areaname,0,v_temp_index-1);
                        --v_temp:=v_city;    
                     --  dbms_output.put_line('省>>>'||v_province||'---市:>>>>'||v_city);   
                  end if;
                      
              
                  
                 if(v_city_index>0 and v_province_index=0 and v_county_index=0) then  ---市存在     
                   v_city:=substr(v_areaname,0,v_city_index-1);
                  -- dbms_output.put_line('---市>>>>'||v_city||'-----記錄id:'||v_id);
                 end if;
                 
                
                 if(v_city_index=0 and v_province_index>0 and v_county_index>0) then  ---省縣存在 
                   v_province:=substr(v_areaname,0,v_province_index-1);
                   v_areaname:=substr(v_areaname,v_province_index+1);    
                   v_temp_index:=instr(v_areaname,'縣');
                   v_county:=substr(v_areaname,0,v_temp_index-1);
                   if(length(v_county)=1)then
                         v_county:=v_county||'縣';
                         end if;
                         
                         
                         
                        begin
    
                           select citycode into v_city_parent_code from T_CITY_MODEL t where t.cityname like '%'||v_provinceName||'%' and leaf =0;--省id
                          -- dbms_output.put_line(v_city_parent_code); 
                            select parentcode into v_city_code from T_CITY_MODEL t where t.cityname =v_county and leaf=2 and t.citycode like '%'||substr(v_city_parent_code,0,2)||'%';---市id
                          -- dbms_output.put_line(v_provinceName||'----'||v_county||'----'||v_city_code||'----------'||v_city_parent_code);
                           select citycode,cityname into v_city_code,v_city_name from T_CITY_MODEL where citycode=v_city_code and parentcode = v_city_parent_code;
                            exception 
                                  when no_data_found then 
                                  v_city_code :='null';          
                                  v_city_name :='null';
                                  v_city_parent_code :='null';
                       end;
                              
                        update  temp_city t set t.city=v_city_name,t.citycode=v_city_code where t.id=v_id;
                             
                        commit; 
               ---  dbms_output.put_line('省>>>'||v_province||'---縣:>>>>'||v_county);
                 end if;
                
              if(v_province_index=0 and v_city_index=0 and v_county_index=0)then
                 --  dbms_output.put_line('省市縣都不存在'||'市:'||v_temp||'縣'||v_county);
                   v_temp:='';
                   v_county:='';
                   
                end if;
               
                    -------------------   
                    -- dbms_output.put_line('省:'||v_province||'>>>市:'||v_temp||'>>>縣:'||v_county);
                    if(v_city_index>0) then


                    open c_city_byname(v_city);
                    
                      fetch c_city_byname into v_city_name,v_city_code,v_city_parent_code,v_leaf;
                            while c_city_byname%found loop 
                              
                            begin
                                --- dbms_output.put_line('----------:'||v_city_name);
                               if(v_leaf=2) then ----是縣級市 (存在很多名字一樣的縣級單位)            
                                          ---根據城市名稱找到省code
                                         ----select parentcode into v_city_parent_code from T_CITY_MODEL where cityname = v_city and leaf = 2;
                                              open c_county_byname(v_city);
                                              
                                                fetch c_county_byname into v_county_name,v_county_code,v_county_parent_code,v_leaf;
                                                      while c_county_byname%found loop 
                                                        select cityname into v_city_name from T_CITY_MODEL where citycode = v_city_parent_code; 
                                                       --dbms_output.put_line('-------v_city_code---:'||v_city_code||'----v_city_parent_code---:'||v_city_parent_code);
                                                       update  temp_city t set t.city=v_city_name,t.citycode=v_city_parent_code where t.id=v_id;
                                                        commit;  
                                                       /* begin 
                                                              if(v_county_parent_code=v_city_code)then
                                                                    select cityname into v_city_name from T_CITY_MODEL where citycode = v_city_parent_code; 
                                                                   dbms_output.put_line('----------:'||v_city_name);         
                                                                    update  temp_city t set t.city=v_city_name,t.citycode=v_city_parent_code where t.id=v_id;
                                                                    commit; 
                                                              end if;
                                                               \* exception
                                                                when no_data_found then 
                                                                v_city_code :='null';          
                                                                v_city_name :='null';*\
                                                               
                                                          end;    */
                                                      fetch c_county_byname into v_city_name,v_city_code,v_city_parent_code,v_leaf;
                                                      end loop;
                                                      close c_county_byname;  
                                        
                                   elsif(v_leaf=1) then               
                                          select citycode into v_city_code from T_CITY_MODEL where cityname = v_city and leaf = 1;
                                         --  dbms_output.put_line('----------:'||v_id);
                                          update  temp_city t set t.city=v_city,t.citycode=v_city_code where t.id=v_id;
                                          commit; 
                                     end if;
                                  /*  exception 
                                    when no_data_found then 
                                    v_city_code :='null';          
                                    v_city_name :='null';*/
                                   
                              end;
                                     
                            fetch c_city_byname into v_city_name,v_city_code,v_city_parent_code,v_leaf;
                            end loop;
                            close c_city_byname;   
                    end if;  
                                    
             fetch c_project_cursor into v_id,v_areaname,v_provinceName;
     end loop;
  close c_project_cursor;
  
 EXCEPTION
  WHEN OTHERS  THEN 
 /* v_city_code :='null';          
  v_city_name :='null';
  v_city_parent_code :='null';*/
    
   v_ErrorCode := SQLCODE;  
   v_ErrorText := SUBSTR(SQLERRM, 1, 200);      
   --dbms_output.put_line(v_ErrorCode || '::'||v_ErrorText);  


end;

有些時候使用sql 處理還是挺方便的

這裡要注意一點 使用遊標的過程中如果出現異常就會跳出迴圈不除錯的話根本看不出來問題出在哪兒  所以最好還是加上異常處理