`
吃猫的鱼
  • 浏览: 45791 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

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<String> tableRelaList= new ArrayList<String>();//存放表的连接关系
		
		String[] srcTables = fromString.split(",");			//源表数组
		List<String> srcTableList = new ArrayList<String>(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<index_equ) {				// (+) 在 = 左边,左关联
					if (lastTable!=null&&lastTable.equals(table1)) {
						tableRelaList.add(" LEFT JOIN "+table2+" ON "+whereTmp[i].replace("(+)", ""));
					}else {
						tableRelaList.add(table1+" LEFT JOIN "+table2+" ON "+whereTmp[i].replace("(+)", ""));
					}					
				}else {						// (+) 在 = 右边,右关联
					if (lastTable!=null&&lastTable.equals(table1)) {
						tableRelaList.add(" RIGHT JOIN "+table2+" ON "+ whereTmp[i].replace("(+)", ""));
					}else {
						tableRelaList.add(table1+" RIGHT JOIN "+table2+" ON "+ whereTmp[i].replace("(+)", ""));
					}										
				}
				lastTable = table1;
			}
		}			
		if (srcTableList!=null&&srcTableList.size()!=0) {
			fromString =this.listToString(tableRelaList) + "," +this.listToString(srcTableList);	//拼接from串
		}else {
			fromString =this.listToString(tableRelaList);
		}
		whereString = whereString.length()==0?whereString.append(" 1=1 "):whereString;
		return fromString+" where "+whereString;
	}	
	
	/**
	 * list转字符串
	 * @param list
	 * @return	转换后的字符串
	 */
	private String listToString(List<String> list) {
		StringBuffer temp = new StringBuffer() ;
		Iterator<String> 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-SERVER-64位配置ORACLE连接-中文乱码问题

    ### SQL-SERVER-64位配置ORACLE连接-中文乱码问题 在IT行业中,不同数据库之间的连接配置是一项常见的任务,特别是在需要实现跨平台数据交换的场景下。本文将详细介绍如何解决64位系统下的SQL Server连接Oracle...

    oracle-查找硬解析问题SQL语句

    在数据库中硬解析是万恶之源,为大家提供一个查找并且定位oracle硬解析问题SQL语句脚本

    pl/sql配置

    在IT领域,特别是数据库开发与管理中,PL/SQL(Procedural Language for SQL)作为Oracle数据库的标准编程语言,其工具的配置优化对于提升开发效率、代码质量和用户体验至关重要。以下是对“PL/SQL配置”这一主题的...

    jdbc-oracle-thinjdbc-oracle-thin

    在数据库连接技术中,Java Database Connectivity (JDBC) 是一种用于执行 SQL 语句的标准 Java API,可以为多种关系数据库提供统一访问。其中,Oracle 提供了两种主要类型的 JDBC 驱动:JDBC-Oracle-Thin 和 OCI...

    ORACLE-SQL性能优化大全.pdf

    - **共享SQL区域**:Oracle会在内存的共享池中缓存已执行过的SQL语句,以便后续执行时可以直接使用而无需重新解析。 - **SQL语句处理的阶段**:包括解析、执行、归还等阶段。 - **共享游标**:多个SQL语句如果...

    深入解析Oracle--DBA入门、进阶与诊断案例

    本篇文章将根据提供的资料,深入解析Oracle DBA的入门、进阶及诊断案例。 一、Oracle DBA入门 1. 数据库概念:理解数据库的基本构成,如表空间、数据文件、控制文件、重做日志、实例等。 2. 安装与配置:学习如何在...

    oracle SQL疑难解析 书中SQL

    在"oracle-sql-recipes-master"这个压缩包中,很可能是包含了书中的示例代码和练习,帮助读者深入理解和应用书中的知识点。以下是基于Oracle SQL的一些关键知识点的详细解析: 1. **SQL基础**:SQL(Structured ...

    Oracle-SQL-statements-efficiency.rar_oracle

    1. **SQL Profiling**:Oracle提供了SQL Profiling工具,通过分析SQL执行过程中的时间分布,找出哪些部分消耗最多的时间,从而定位问题。 2. **V$SQL视图**:通过查询V$SQL视图,可以获取到SQL语句的执行统计信息,...

    ORACLE数据库SQL优化---表连接类型.docx

    Oracle优化器在解析SQL语句时,必须决定表的连接顺序,这对执行性能至关重要。它会先将两个表两两连接,然后逐步连接所有表。这个过程中,优化器需要确定哪个表作为驱动表(outer table),哪个作为被驱动表(inner ...

    ogg sqlserver-oracle mysql-oracle mysql-mysql的同步配置参考

    在本配置参考中,我们将探讨如何使用Oracle GoldenGate(简称OGG)来实现SQL Server到Oracle,MySQL到Oracle以及MySQL到MySQL的同步配置。 1. SQL Server到Oracle的同步配置: - 首先,你需要在SQL Server上安装并...

    盖国强_深入解析Oracle-数据库的初始化

    《盖国强_深入解析Oracle-数据库的初始化》是盖国强大师关于Oracle数据库初始化过程的深入解析之作。盖国强不仅是中国第一个获得Oracle ACE及ACE总监头衔的专家,而且拥有超过十年的Oracle数据库经验,并持续活跃在...

    ORACLE-SQL优化

    ORACLE优化器负责解析SQL语句并生成执行计划。优化器有两种模式:基于规则的优化器(RBO)和基于成本的优化器(CBO)。CBO是当前推荐使用的优化器类型,因为它基于数据分布和硬件特性的统计信息来计算执行路径的成本...

    Oracle-sql-Performance-Tuning-30Tips.rar_oracle_tom kyte

    "Oracle SQL Performance Tuning 39Tips" 提供了由Oracle专家Tom Kyte精心总结的30个SQL优化技巧,这些技巧旨在帮助用户提升数据库查询速度,减少资源消耗,提高系统整体性能。 1. **索引优化**:Tom Kyte强调了...

    Sqldbx连接OracleX64位,前一个版本放少东西了

    标题“Sqldbx连接OracleX64位,前一个版本放少东西了”指出,用户在尝试使用Sqldbx连接到Oracle 64位数据库时遇到了问题,原因是前一个版本的安装或配置可能不完整。Sqldbx是一款开源的SQL查询工具,它支持多种...

    oracle-sql优化

    4. **SQL处理过程**:SQL在Oracle中的处理包括共享SQL区域、SQL处理阶段、共享游标和SQL编码标准。共享游标允许重用已解析的SQL,提高执行速度。 5. **SQL优化策略**:包括调整业务逻辑、数据设计、流程设计、SQL...

    Oracle-SQL-练习题及标准答案.doc

    ### Oracle-SQL-练习题及标准答案解析 #### 数据库设计与操作 本文档提供了一系列针对Oracle SQL的练习题目,并附带了解答示例。通过这些题目,学习者能够掌握Oracle SQL的基础到进阶技能,包括但不限于数据表的...

    java的sql解析器jsqlparser

    Java的SQL解析器JSQLPaser是一个强大的开源库,专门设计用于处理SQL语句的解析工作。这个库允许开发者分析SQL语句的结构,提取出其中的关键元素,如列名、表名、别名以及查询条件,从而在Java应用程序中实现对SQL的...

    mysql_sqlserver_oracle-jdbc.rar

    标题中的"mysql_sqlserver_oracle-jdbc.rar"表明这是一个压缩包,包含了与MySQL、SQL Server和Oracle数据库相关的JDBC驱动程序。JDBC(Java Database Connectivity)是Java编程语言用来规范应用程序如何访问数据库的...

    ORACLE-plan-a-sql-tuning.rar_oracle

    "ORACLE-plan-a-sql-tuning.rar_oracle"这个压缩包显然包含了关于Oracle SQL调优的培训材料,特别是"ORACLE执行计划和SQL调优.ppt",这可能是一个详细的PPT演示文稿,用于解释如何理解执行计划以及如何进行SQL优化。...

    oracle-sql资料必备

    Oracle SQL是数据库管理员、开发人员和分析师在处理Oracle数据库系统时不可或缺的工具。它是一种用于查询、更新和管理Oracle数据库的强大语言。以下是一些关于Oracle SQL的重要知识点,这些知识点涵盖了从基础到高级...

Global site tag (gtag.js) - Google Analytics