SQL解析(Oracle -> 标准SQL,左右连接部分)

阅读更多

    最近有用到HSQL内存数据库,感觉轻巧,方便,只可惜有一定的局限性,毕竟是内存级的,这不,就遇到一个问题,上周五也去论坛上提了问,但是回答者寥寥无几(其实就两个),也许是我提的问题水平太低了,不能吸引大家眼球,呵呵…
    先看问题描叙,下面的sql在Oracle中很显然是支持的:

from table1 a,table2 b,table3 c,table4 d
where  a.emp = '100' 
   and a.type = b.type_id 
   and a.id = c.id(+) 
   and a.area(+) = d.area_id 
   and d.code = 10

    但是在HSQL中不被支持,因为这个是Oracle语法,不是标准的SQL语法,标准的应该用左右连接来替代,如下:    

from TABLE1 A RIGHT JOIN TABLE3 C ON A.ID = C.ID LEFT JOIN TABLE4 D ON A.AREA = D.AREA_ID,TABLE2 B 
where A.EMP = '100' 
  AND A.TYPE = B.TYPE_ID 
  AND D.CODE = 10

   问题就是这样。

   今天总算是吧问题解决了,总体思路也不罗嗦了,直接上代码,理解有问题,或者认为程序有问题的,欢迎大家留言讨论,交流。

   

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class AnalysSQL {
	
	public static void main(String args[]){
		String fromString = "table1 a,table2 b,table3 c,table4 d";
		String whereString = "a.emp = '100' and a.type = b.type_id and a.id = c.id(+) and  a.area(+) = d.area_id and d.code = 10";
		AnalysSQL test = new AnalysSQL();
		String fromWhere = test.transCondition(fromString, whereString);
		System.out.println(fromWhere);
	}

	/**
	 * 解析SQL中from和where后面的串 
	 * @param fromString		from 串
	 * @param whereCondition	where 串
	 * @return	from 后面的整串,含where关键字
	 */
	private String transCondition(String fromString,String whereCondition) {
		fromString = fromString.toUpperCase().trim();	//from串转大写去空格
		whereCondition = whereCondition.toUpperCase().trim();//where串转大写去空格
		
		StringBuffer whereString = new StringBuffer();	//存放where条件
		List tableRelaList= new ArrayList();//存放表的连接关系
		
		String[] srcTables = fromString.split(",");			//源表数组
		List srcTableList = new ArrayList(Arrays.asList(srcTables));//源表数组转List集合
		
		String[] whereTmp = whereCondition.split("AND");
		String lastTable = null;
		for (int i = 0; i < whereTmp.length; i++) {		//where条件处理
			whereTmp[i] = whereTmp[i].trim();
			int index = whereTmp[i].indexOf("(+)");		//确定(+)位置
			if (index == -1) {
				if (whereString.length()==0) {
					whereString.append(whereTmp[i]);
				}else {
					whereString.append(" AND "+whereTmp[i]);
				}		
			}else {
				int index_equ = whereTmp[i].indexOf("=");// 确定等号位置
				String[] tmp1 = whereTmp[i].split("="); 	// 按 = 拆分		
				String left = tmp1[0].trim();			//	= 左边
				String right = tmp1[1].trim();			//	= 右边
				String table1 = left.split("\\.")[0];//  = 左边部分按 . 拆分后,第一个位置为表1
				String table2 = right.split("\\.")[0];//  = 右边部分按 . 拆分后,第一个位置为表2
											
				for (int j = 0; j < srcTables.length; j++) {//源表处理,源表集合中移除有连接关系表
					srcTables[j] = srcTables[j].trim();
					if (srcTables[j].lastIndexOf(table1) != -1) {
						table1 = srcTables[j];
						srcTableList.remove(srcTables[j]);			
						continue;
					}
					if (srcTables[j].lastIndexOf(table2) != -1) {
						table2 = srcTables[j];
						srcTableList.remove(srcTables[j]);
					}
				}
				
				if (index list) {
		StringBuffer temp = new StringBuffer() ;
		Iterator iterator = list.iterator() ;
		boolean flag = true;		//开关控制,用于第一次
		while (iterator.hasNext()) {
			String tmp = iterator.next().trim();
			if (flag) {
				temp.append(tmp);
				flag = false;
				continue;
			}			
			if (tmp.startsWith("LEFT")||tmp.startsWith("RIGHT")) {
				temp.append(" "+tmp);
			}else {
				temp.append(", "+tmp);
			}			
		}
		return temp.toString();
	}	
} 

    很希望能和大家一起交流,大家可以随意发表自己的看法。个人觉得这段程序太冗余,不够精简。。。。

你可能感兴趣的:(SQL,Oracle,J#,C,C++)