oracle表分区查询的使用

做了一个前台使用FLEX、后台使用JAVA、数据库使用的是ORACLE的这样一个工程.flex与java采用blazeDS进行通信。

项目中有个模块需要查询报警信息,而报警信息表的数据量又特别大,所以就根据报警信息表,在oracle中建立了几个分区。(每个月的数据是一个分区),进行分区查询。

--查询某个表下面某个分区的所有信息
select * from tmgpshis.tm_bus_warn_message_his PARTITION(P_WARN_MESSAGE_HIS_201304);

--表名必须要大写  查询某个表下面 所有的分区信息
SELECT PARTITION_NAME FROM DBA_TAB_PARTITIONS WHERE TABLE_NAME='TM_BUS_WARN_MESSAGE_HIS'

具体设计如下:

1  由于数据量非常大,在用户输入时间段查询数据的时候,限制了只能输入30天之内的数据。当然可以跨月查询。核心flex as代码如下:

 //结束时间只能选择比开始时间小1个月的。
private function oneMonthControl(stTempStr:String,etTempStr:String):Boolean{
 // 标志位
var isTimeFlag:Boolean = false ;
stTempStr = stTempStr.substring(0,4)+stTempStr.substring(5,7)+stTempStr.substring(8,10);
etTempStr = etTempStr.substring(0,4)+etTempStr.substring(5,7)+etTempStr.substring(8,10);
var sdataTime:Date = new Date(stTempStr.substring(0,4),stTempStr.substring(4,6),stTempStr.substr(6,8));
var gdataTime:Date = new Date(etTempStr.substring(0,4),etTempStr.substring(4,6),etTempStr.substr(6,8));
var num:Number = gdataTime.getTime() - sdataTime.getTime();
var millisecondsPerMinute:int = 1000 * 60;
var millisecondsPerHour:int = 1000 * 60 * 60;
var millisecondsPerDay:int = 1000 * 60 * 60 * 24;
var nday:Number = num / millisecondsPerDay;//日间隔
  if(nday>30){
isTimeFlag=false;
    }else{
    isTimeFlag = true;
}
    return isTimeFlag;
}

2 如果开始时间和结束时间,在当前时间的这一周内。直接查询这个当前表。核心flex as 代码如下:

//判断两个时间差 ,是否在当前时间一周内!
private function decideTime(stTempStr:String,etTempStr:String):Boolean{
			
				//得到系统的当前时间
				var today:Date=new Date();
				var dateFormatter:DateFormatter = new DateFormatter(); 
				dateFormatter.formatString = "YYYYMMDD"; //YYYY-MM-DD JJ:NN:SS
				var now:String= dateFormatter.format(today); 
				// 标志位
				var isTimeFlag:Boolean = false ;
				stTempStr =	stTempStr.substring(0,4)+stTempStr.substring(5,7)+stTempStr.substring(8,10);
				etTempStr =	etTempStr.substring(0,4)+etTempStr.substring(5,7)+etTempStr.substring(8,10);
				var sdataTime:Date = new Date(stTempStr.substring(0,4),stTempStr.substring(4,6),stTempStr.substr(6,8));
				var gdataTime:Date = new Date(etTempStr.substring(0,4),etTempStr.substring(4,6),etTempStr.substr(6,8));
				var num:Number = gdataTime.getTime() - sdataTime.getTime();
				var millisecondsPerMinute:int = 1000 * 60;
				var millisecondsPerHour:int = 1000 * 60 * 60;
				var millisecondsPerDay:int = 1000 * 60 * 60 * 24;
				var nday:Number = num / millisecondsPerDay;//日间隔
				if(stTempStr.substring(4,6) == now.substring(4,6)){
					//判定
					if(nday >= 1 && nday<=6){
						isTimeFlag=true;
					}
				}
				return isTimeFlag;
			}


 

//如果 开始时间和结束时间,在当前时间的这一周内。
					if(decideTime(detailSt,detailEt)==true){
						var token:AsyncToken = busAlermDetail.queryAlermDetailInfos(getSql(detailSt,detailEt));
						FlexUtil.addResponder(token,aAllConResultHandler,aAllConFaultHandler); 
						UIWaiting.popWaiting(""); 
					//如果不是当前时间的当前一周。
					}

3 如果不是当前时间的当前一周。先判断一下数据库中这个表是否有相应的分区。如果有相应的分区,则进行逻辑判断。核java代码,flex as 代码如下:

//查询到有分区
			private function isHaveResHandler(event:ResultEvent):void{
				
					isHavePar = event.result as String;
					
					//如果开始月份在分区里面,结束月份不在分区里面。
					if(isHavePar=="1"){
						var staOthSql:String=getStartPartSql(detailSt,detailEt)+"union"+" "+getotherPartSql(detailSt,detailEt);
						var staOthToken:AsyncToken = busAlermDetail.queryAlermDetailInfos(staOthSql);
						FlexUtil.addResponder(staOthToken,aAllConResultHandler,aAllConFaultHandler); 
						UIWaiting.popWaiting(""); 
					}
					
					// 开始月份、结束月份都不在分区内
					if(isHavePar=="2"){
						var stetToken:AsyncToken = busAlermDetail.queryAlermDetailInfos(getotherPartSql(detailSt,detailEt));
						FlexUtil.addResponder(stetToken,aAllConResultHandler,aAllConFaultHandler); 
						UIWaiting.popWaiting("");  
					}
					
					//如果开始月份不在分区里面,结束月份在分区里面。
					if(isHavePar=="3"){
						var othEndSql:String=getotherPartSql(detailSt,detailEt)+"union"+" "+getEndPartSql(detailSt,detailEt);
						var othEndToken:AsyncToken = busAlermDetail.queryAlermDetailInfos(othEndSql);
						FlexUtil.addResponder(othEndToken,aAllConResultHandler,aAllConFaultHandler); 
						UIWaiting.popWaiting(""); 
					}
					//如果开始月份在分区里面,结束月份也在分区里面。
					if(isHavePar=="4"){
						
						//在同一分区中的月份
						if(detailSt.substring(5,7)==detailEt.substring(5,7)){
							//在同分区,不包括当前一周。
							var sanToken:AsyncToken = busAlermDetail.queryAlermDetailInfos(getEndPartSql(detailSt,detailEt));
							FlexUtil.addResponder(sanToken,aAllConResultHandler,aAllConFaultHandler); 
							UIWaiting.popWaiting("");  
							//开始月份与结束月份不一致
						}else{
							
							//开始分区并上结束分区
							var unionsql:String=getStartPartSql(detailSt,detailEt)+"union"+" "+getEndPartSql(detailSt,detailEt);
							var unionToken:AsyncToken = busAlermDetail.queryAlermDetailInfos(unionsql);
							FlexUtil.addResponder(unionToken,aAllConResultHandler,aAllConFaultHandler); 
							UIWaiting.popWaiting(""); 
						}
					}
			}


 

//得到分区sql
			private function getotherPartSql(stOther:String,etOther:String):String
			{
				partParam = "OTHER" ;
				var  othersql:String="select t.bus_job_no busJobNo,to_char(t.ins_time,'YYYY-MM-DD HH24:MI:SS') insTime ,t.LINE_NO lineNo,t.warning_message warningMessage,t.warn_level warnLevel  from tmgpshis.tm_bus_warn_message_his  PARTITION (WARN_MESSAGE_"+partParam+") t where 1=1 ";
				if(line.selectedItem !=null && line.selectedItem!="")
				{
					othersql+="  and t.line_no ='"+line.selectedItem.id+"' ";
				}
				if(bus.selectedItem !=null && bus.selectedItem!="")
				{
					othersql+="  and t.bus_job_no ='"+bus.selectedItem.name+"' ";
				}
				
				if(conalermType.selectedItem != null && conalermType.selectedItem != ""){ 
					
					trace(conalermType.selectedItem.ALERMTYPE as String);
					var alt:String =conalermType.selectedItem.ALERMTYPE as String ;
					othersql += " and t.WARNING_MESSAGE ='"+alt+"'";
				}
				
				
				var otherasel:String="";
				
				if(alermStateL.selectedItem == "未处理"){
					otherasel="0";
					
				}else if(alermStateL.selectedItem == "已处理"){
					otherasel="1";
					
				}else if(alermStateL.selectedItem == "将来处理"){
					otherasel="2";
				}else{
					otherasel="";
				}
				if(otherasel!="")
				{
					othersql+="  and t.ishandle="+otherasel+"";
				} 
				
				othersql+=" and  t.ins_time between TO_DATE('"+stOther+"', 'YYYY-MM-DD HH24:MI:SS')" +
					" and TO_DATE('"+etOther+"', 'YYYY-MM-DD HH24:MI:SS')";
				othersql+=" and t.line_no in ("+lineNos+")";
				
				return othersql;
			}
			
public String isHasPart(String stTime ,String etTime) {
		String resStr = "0" ;
		List<PartitionInfo> partBeanList = new ArrayList<PartitionInfo>();
		partBeanList = queryAlermDetailInfoDao.isHasPart();

		List<String> partNameStrList = new ArrayList<String>();
		
		PartitionInfo po = new PartitionInfo();
		
		for(int i=0;i<partBeanList.size();i++){
			po = partBeanList.get(i);
			String parName = po.getPartitionName();
			String monthN = rightStr(parName,2);
			partNameStrList.add(monthN);
		}
		
		if(partNameStrList.contains(stTime) && !partNameStrList.contains(etTime)){
			resStr = "1" ;
		}else if(!partNameStrList.contains(stTime) && !partNameStrList.contains(etTime)){
			resStr = "2" ;
		}else if(!partNameStrList.contains(stTime) && partNameStrList.contains(etTime)){
			resStr = "3" ;
		}else if(partNameStrList.contains(stTime) && partNameStrList.contains(etTime)){
			resStr = "4" ;
		}
		
		return resStr;
	}


 

//分区判断
	public List<PartitionInfo> isHasPart(){
		//查询所有的分区
		String partSql = "SELECT PARTITION_NAME FROM DBA_TAB_PARTITIONS WHERE TABLE_NAME='TM_BUS_WARN_MESSAGE_HIS'";
		
		//集合list
		List<PartitionInfo> partList = new ArrayList<PartitionInfo>();
		
		partList = jdbcTemplate.query(partSql,new PartitionInfoMapper());
		
		return partList ;
	}
	
	/**
	 * 分区Mapper
	 * @author han
	 */
	class PartitionInfoMapper implements RowMapper<PartitionInfo>{

		public PartitionInfo mapRow(ResultSet rs, int rn)
				throws SQLException {
			
			PartitionInfo partBean = new PartitionInfo();
			
			partBean.setPartitionName(rs.getString("PARTITION_NAME"));
			
			return partBean;
		}
		
	}

4  注意。需要注意2点,第一个就是如果之后再增加新的分区,代码可以不用修改,直接可以用。就是在写代码的时候,尽量用动态的参数,不要写死。第二个就是由于flex是异步执行的,看下图所示:

 

 结束。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值