1、分区表创建:     对轨迹表T_TRACK进行组合分区,首选按轨迹时间T_TRACK_TM进行区间分区,然后,再根据公司代码C_COMP_CDE进行列表分区。 
  create table T_TRACK  (
     N_TRACK_ID           NUMBER(20)                      not null,  
     C_COMP_CDE           VARCHAR2(6),
     T_TRACK_TM           DATE                            not null,
     C_CAR_NO             VARCHAR2(50) 
  )partition by range(T_TRACK_TM)
  subpartition by list(C_COMP_CDE)
  (
               partition P_2009_11 values less than (to_date('2009-12-01','yyyy-MM-dd'))
               (
                         subpartition P_2009_11_P1013 values('P1013')
               )
  );
  
2、常用操作语句:  
  
  --添加子分区
  alter table T_TRACK 
  modify partition P_2005_01
  add subpartition P_2005_01_P1017 values('P1017');
  
  --添加分区
  alter table T_TRACK add partition P_2005_04 values less than(to_date('2005-05-01','yyyy-MM-dd'))
  (
      subpartition P_2005_04_P1013 values('P1013'),
      subpartition P_2005_04_P1013 values('P1014'),
      subpartition P_2005_04_P1013 values('P1015'),
      subpartition P_2005_04_P1013 values('P1016')
  )
  
  --删除子分区
  alter table T_TRACK drop subpartition p_2005_01_p1017;
  
  --删除分区
  alter table T_TRACK drop partition p_2005_04;
  
  
  
3、书写ORACLE包封装创建分区 
包声明   /**//*
  需要的权限:
  选择视图:dba_tablespace,dba_tab_parition,dba_tab_subpartition
  创建表空间的权限
  同时,在包体实现中,指明表空间存放路径
  */
  --包声明
  create or replace package GPS_PARTITION is
     /**//*判断表空间是否已经存在*/
    function tableSpaceExist(tableSpaceName varchar2) return boolean;  
     /**//*创建表空间*/
    procedure createTableSpace(tableSpaceName varchar2);
    
     /**//*判断分区是否存在*/
    function partitionExist(tableName varchar2,partitionName varchar2) return boolean;
     /**//*判断子分区是否存在*/
    function subPartitionExist(tableName varchar2,subPartitionName varchar2) return boolean;  
    
     /**//*删除分区*/
    procedure dropPartition(tableName varchar2,partitionName varchar2);
     /**//*删除子分区*/
    procedure dropSubPartition(tableName varchar2,subPartitionName varchar2);
    
    --供DBA使用
     /**//*新建当年的分区,供年初始DBA调用*/
    procedure createAYearPartition(tableName varchar2,startMonth date);
     /**//*新建某月分区(子分区按公司分,从公司表中取),供每月DBA调用*/
    procedure addAMonthPartition(tableName varchar2,theMonth date); 
    
    
    --供应用程序调用
     /**//*新增某公司一年内的所有分区*/
    procedure addACompOneYearPartition(tableName varchar2,startMonth date,compCde varchar2);
     /**//*新增某公司一月的分区*/
    procedure addACompOneMonthPartition(tableName varchar2,theMonth date,compCde varchar2);
   
   
  end GPS_PARTITION;
包实现:  create or replace package body GPS_PARTITION is
     /**//*公司游标*/
    cursor corpCursor is 
           select distinct(c_comp_cde) from t_sys_corp where c_is_available='1';  
    upperTableName varchar2(80);
    upperTableSpaceName varchar2(80);--TS_P1013
    upperCompCde varchar2(5);
    tableSpaceDir varchar2(100):='d:\oracle\tbtest\';
    
     /**//*判断表空间是否已经存在*/
    function tableSpaceExist(tableSpaceName varchar2) return boolean is    
    resultNum number :=0;
    
    begin
             upperTableSpaceName := UPPER(tableSpaceName);
               resultNum:=0;
             dbms_output.put_line('判断表空间'||upperTableSpaceName||'是否存在:');
             select count(*) into resultNum from dba_tablespaces where tablespace_name=upperTableSpaceName;
             dbms_output.put_line('结果是(大于0存在,小于0不存在):'||resultNum);
             if (resultNum>0) then
               return true;
             else
               return false;
             end if;   
    end;
    
     /**//*创建表空间*/
    procedure createTableSpace(tableSpaceName varchar2)
    is 
    tablespaceSql varchar2(500);
    begin
          tablespaceSql:='create tablespace '||tableSpaceName||' datafile ''' ||
          tableSpaceDir||tableSpaceName||'.dbf'''||' size 10M reuse default storage(initial 512K next 512K minextents 8 maxextents 4096 pctincrease 0) online permanent';   
          dbms_output.put_line(tablespaceSql);
          execute immediate tablespaceSql;
    end;
    
     /**//*判断分区是否存在*/
    function partitionExist(tableName varchar2,partitionName varchar2) return boolean is
    resultNum number :=0;
    begin
             upperTableName := UPPER(tableName);
               dbms_output.put_line('判断分区'||partitionName||'在表'||tableName||'中是否存在:');
             resultNum:=0;
             select count(*) into resultNum from dba_tab_subpartitions where partition_name=partitionName and table_name=upperTableName;      
             dbms_output.put_line('select count(*) into resultNum from dba_tab_subpartitions where partition_name='||partitionName||' and table_name='||upperTableName);
             dbms_output.put_line('结果是(大于0存在,小于0不存在):'||resultNum);
             if (resultNum>0) then
               return true;
             else
               return false;
             end if; 
    end;
    
     /**//*判断子分区是否存在*/
    function subPartitionExist(tableName varchar2,subPartitionName varchar2) return boolean
    is
    resultNum number :=0;
    begin
         upperTableName := UPPER(tableName);          
             dbms_output.put_line('判断子分区'||subPartitionName||'在表'||tableName||'中是否存在:');
             resultNum:=0;
             select count(*) into resultNum from dba_tab_subpartitions where table_name=upperTableName and subpartition_name=subPartitionName;     
             dbms_output.put_line('select count(*) into resultNum from dba_tab_subpartitions where subpartition_name='||subPartitionName||' and table_name='||upperTableName);
             dbms_output.put_line('结果是(大于0存在,小于0不存在):'||resultNum);
             
             if (resultNum>0) then
               return true;
             else
               return false;
             end if; 
    end;
      /**//*删除分区*/
    procedure dropPartition(tableName varchar2,partitionName varchar2)
    is
    begin      
    upperTableName := UPPER(tableName);
              execute immediate 
              'alter table '||upperTableName||'drop partition'||partitionName;
    end;
    
     /**//*删除子分区*/
    procedure dropSubPartition(tableName varchar2,subPartitionName varchar2)
    is
    begin
    upperTableName := UPPER(tableName);
              execute immediate 
              'alter table '||upperTableName||'drop subpartition'||subPartitionName;
    end;
    
    
     /**//*新建当年的分区,供年初始DBA调用*/
    procedure createAYearPartition(tableName varchar2,startMonth date)
    is
    monthNum number; 
    theMonth date;
    begin
    upperTableName := UPPER(tableName);
          theMonth := startMonth;
                  
          monthNum := to_char(startMonth,'MM');
          while monthNum12 loop 
                addAMonthPartition(upperTableName,theMonth);
                theMonth := theMonth+numtoyminterval(1,'month');
                monthNum := to_char(theMonth,'MM');
          end loop;    
          
          if monthNum=12 then
             addAMonthPartition(upperTableName,theMonth);
          end if;    
    end;
    
    
     /**//*新建某月分区(子分区按公司分,从公司表中取),供每月DBA调用*/
    procedure addAMonthPartition(tableName varchar2,theMonth date)
    is
              
              compCde varchar2(5);
              
    begin
        upperTableName := UPPER(tableName);      
              
              if corpCursor%ISOPEN then
                   close corpCursor;   
              end if;       
              open corpCursor;
              
              fetch corpCursor into compCde;
              if corpCursor%found then
                 addACompOneMonthPartition(tableName,theMonth,compCde);
              end if;
               while corpCursor%found loop
                    fetch corpCursor into compCde;
             
                    if corpCursor%found then
                        addACompOneMonthPartition(tableName,theMonth,compCde);
                    end if;
                        
              end loop;
              close corpCursor;
              
              
    end;
    
     /**//*新增某公司一月的分区*/
    procedure addACompOneMonthPartition(tableName varchar2,theMonth date,compCde varchar2)
    is
              yearStr varchar2(4);--年
              monthNum number;  --月
              partitionName varchar2(9);--P_2009_12
              subPartitionName varchar2(15);--P_2009_12_P1013
              maxDate varchar2(10);
              sqlStr varchar2(2000);--要执行的SQL语句
        
    begin     
              yearStr:=to_char(theMonth,'yyyy');  
              
              upperTableName := UPPER(tableName);
              upperCompCde := UPPER(compCde);
              upperTableSpaceName := 'TS_'||upperCompCde||'_'||yearStr;
              
              if not tableSpaceExist(upperTableSpaceName) then
                 createTableSpace(upperTableSpaceName);
              end if;
              
              
              yearStr:=to_char(theMonth,'yyyy');  
              monthNum := to_char(theMonth,'MM');
              if monthNum=12 then
                 maxDate:=yearStr+1;
                 maxDate:=maxDate||'-01'||'-01';
              else
                 maxDate:=yearStr||'-'||lpad((monthNum+1),2,'0')||'-01';
              end if; 
              
              partitionName:='P_'||yearStr||'_'||lpad((monthNum),2,'0');
              subPartitionName:=partitionName||'_'||upperCompCde;
             
              
              if partitionExist(upperTableName,partitionName) then               
                 --分区存在               
                 if not subPartitionExist(upperTableName,subPartitionName) then
                    sqlStr:='alter table '||upperTableName||' modify partition '||partitionName
                               ||' add subpartition '||subPartitionName||' values('''||upperCompCde||''') tablespace '||upperTableSpaceName;
                 end if;
              else
                 --分区不存在               
                 sqlStr:='alter table '||upperTableName||' add partition '||partitionName
                             ||' values less than(to_date('''||maxDate||''',''yyyy-MM-dd''))('
                             ||' subpartition '||subPartitionName||' values('''||upperCompCde||''')'||' tablespace '||upperTableSpaceName||' )';
                 
              end if;
              
              
              if length(sqlStr)>0 then
                 dbms_output.put_line('执行创建分区或子分区语句:'||sqlStr);
                 execute immediate sqlStr;
              end if;
    end;
    
      
     /**//*新增某公司一年内的所有分区*/
    procedure addACompOneYearPartition(tableName varchar2,startMonth date,compCde varchar2)
    is
    monthNum number; 
    theMonth date;
    begin
          upperTableName := UPPER(tableName); 
          upperCompCde := UPPER(compCde);
          theMonth := startMonth;
                  
          monthNum := to_char(startMonth,'MM');
          while monthNum12 loop 
                addACompOneMonthPartition(upperTableName,theMonth,compCde);
                theMonth := theMonth+numtoyminterval(1,'month');
                monthNum := to_char(theMonth,'MM');
          end loop;    
          
          if monthNum=12 then
             addACompOneMonthPartition(upperTableName,theMonth,compCde);
          end if;    
    end; 
  end GPS_PARTITION;
    4.新增公司时,通过IBATIS调用存储过程为此公司添加一年的分区
    /** *//**
       * 为公司添加轨迹表一年的分区
       * @param compCde
       * @param date
       * @throws Exception 
       */
       public static void addACompOneYearPartition(String compCde,String date,DAOBase dao) throws Exception {
          
          MapString,String> keys = new HashMapString,String>();
          keys.put("tableName", "T_GPS_TRACK");
          keys.put("compCde", compCde);
          keys.put("theMonth", date);
          
          dao.doView("track.addACompOneYearPartition", keys);
      }
  
IBATIS配置文件:
 
 
  parameterMap id="partitionParam" class="java.util.Map">
          parameter property="tableName" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" />
          parameter property="theMonth" jdbcType="DATE" javaType="java.lang.String" mode="IN" />
          parameter property="compCde" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" />        
       span style="color: #800000">parameterMap>
  
  
  procedure id="addACompOneYearPartition" parameterMap="partitionParam">
         {call gps_partition.addACompOneYearPartition(?,to_date(?,'yyyy-MM-dd'),?)}
      span style="color: #800000">procedure> 
5、查询表中数据时,传入分区:  /**
       * 取得最靠近(=)某时间点的终端的轨迹
       * @param temiId
       * @param theDate
       * @return
       * @throws Exception 
       */
      public Track getCloserLeftTrack(String temiId,
              String theDate,String compCde) throws Exception {
          
          
          Map> keys = new HashMapString, String>();
          keys.put("temiId", temiId);
          keys.put("theDate", theDate);
          keys.put("subPartitionName", TrackPatitionUtils.getSubPartitionName(compCde, theDate));
          Object obj =  dao.doView("track.getCloserLeftTrack", keys);
          if(obj!=null)
              return (Track) obj;
          return null;
      }     /**
       * 取子分区名称
       * 格式:P_YYYY_MM_COMPCDE (如:P_2009_12_P3456) 
       * @param compCde 公司代码
       * @param date
       * @return
       * @throws ParseException 
       */
      public static String getSubPartitionName(String compCde,String date) throws ParseException{
          Assert.notNullAndEmpty(compCde, "取轨迹表分区名称,公司代码不能为空!");
                  
          return getPartitionName(date)+"_"+compCde;
      }
      
      /**
       * 取分区名称
       * 格式:P_YYYY_MM(如:P_2009_12)
       * @param date
       * @return
       * @throws ParseException 
       */
      public static String getPartitionName(String date) throws ParseException{
          
          Assert.notNullAndEmpty(date, "取轨迹表分区名称,时间不能为空!");        
          date = DateUtils.format(DateUtils.parse(date, "yyyy-MM-dd"), "yyyy_MM");
          
          return "P_"+date;
      } 
 
  select * from T_GPS_TRACK 
          isNotEmpty property="subPartitionName" close=" " open=" ">
                subpartition($subPartitionName$)
          span style="color: #800000">isNotEmpty>
          isEmpty property="subPartitionName">
               isNotEmpty property="patitionName" close=" " open=" ">
                    partition($patitionName$)
               span style="color: #800000">isNotEmpty>
          span style="color: #800000">isEmpty>
          where c_device_no=#deviceNo#  
  
	 
	
	
 
 
	    
    
 
				
 |