`

解决表达式解析为sql 语句时遇到除0错误的程序

    博客分类:
  • Java
阅读更多
public class ExprssionHandlerImpl implements ExpressionHandler {

	/*
	 * (no Javadoc) <p>Title: handleExpression</p> <p>Description:
	 * 过滤表达式中为0的除数,同时将表达式转化为合法的sql</p>
	 * @param expression
	 * @return
	 * @see
	 * com.reiyen.htz.database.generateview.ExpressionHandler#handleExpression
	 * (java.lang.String)
	 */

	@Override
	public String handleExpression(String expression) {
		String sql = "";
		Set<String> set = dividerFilter(expression);
		// 如果表达式没有除数
		if (set.size() <= 0) {
			sql = expression;
		}
		else {
			StringBuffer result = new StringBuffer();
			Iterator<String> iterator = set.iterator();
			while (iterator.hasNext()) {
				result.append("nullif(" + iterator.next() + ",0)*");
			}
			result.deleteCharAt(result.length() - 1);
			// 不能用case result when null then null else derivedIndex end as
			sql = " case when  " + result.toString()
			                + " is null then null else " + expression
			                + " end as ";
		}
		return sql;
	}

	/**
	 * <p>
	 * Title: dividerFilter
	 * </p>
	 * <p>
	 * Description: 过滤表达式中的除号"/",得到所有的除数集合
	 * </p>
	 * 
	 * @param expression
	 * @return
	 */
	private Set<String> dividerFilter(String expression) {
		// 去掉原始字符串一个或多个空格
		expression = expression.replaceAll("\\s+", "");
		int index = -1;
		Comparator<String> comparator = new MyComparator();
		// 利用treeSet将长度短的除数排到前面来先判断,如:表达戒a\(b+c\d),则将除数b移到前除数b+c\d前面来,防止出现除数为0的情况出现
		Set<String> dividers = new TreeSet<String>(comparator);
		// 循环检查除号进行过滤,直到检查到过滤后的表达式中没有除号'/',同时使用index将除号的位置标记
		while ((index = expression.indexOf("/", index + 1)) > 0) {
			// 如果除号后面紧跟的是左括号'(',即除数是一个有括号包围的表达式,如:/()。'('这是除数的起点
			if (expression.charAt(index + 1) == '(') {
				// 将位置标记点移动到左括号'('后面的字符上,
				int next = index + 2;
				// 用一个计数器来记录(的数目
				int count = 1;
				// 循环检查括号,检查到左括号'('计数器就加1,如果检查到左括号')',则计数器就减1
				while (count != 0) {
					if (expression.charAt(next) == '(') {
						count++;
					}
					else if (expression.charAt(next) == ')') {
						count--;
					}
					next++;
				}
				// 得到第一表达式中第一层的除数
				String divider = expression.substring(index + 1, next);
				// 使用递归逐层得到除数
				int index1 = divider.indexOf("/", 0);
				if (index1 > 0) {
					Set<String> set = dividerFilter(divider);
					dividers.addAll(set);
				}
				dividers.add(divider);
			}
			else {
				// 除数中没有括号'()',但可能有右括号,如:表达戒a\(b+c\d)中的d);所以要判断右括号')'的情况
				int next = index + 1;
				do {
					char c = expression.charAt(next);
					if (c == '+' || c == '-' || c == '*' || c == '/'
					                || c == ')')
						break;
					else
						next++;
				} while (next < expression.length());
				dividers.add(expression.substring(index + 1, next));
			}
		}
		return dividers;
	}

	public static void main(String args[]) {
		ExpressionHandler handler = new ExprssionHandlerImpl();
		String expression = "a/b + (c/d + f/(d+e))/f + g/p";
		String result = handler.handleExpression(expression);
		System.out.println(result);
	}

}

 比较器:

public class MyComparator implements Comparator<String> {

	public int compare(String arg0, String arg1) {

		int result = 0;
		int len1 = arg0.length();
		int len2 = arg1.length();
		if (len1 < len2) {
			result = -1;
		}
		else if (len1 > len2) {
			result = 1;
		}
		else if (len1 == len2) {
			if (arg0.equals(arg1)) {
				result = 0;
			}
			else {
				result = arg0.compareTo(arg1);
			}
		}
		return result;
	}
}

 比如表达式:"a/b + (c/d + f/(d+e))/f + g/p"

使用此程序解析后输出的sql如下所示:

case when  nullif(b,0)*nullif(d,0)*nullif(f,0)*nullif(p,0)*nullif((d+e),0) is null then null else a/b + (c/d + f/(d+e))/f + g/p end as
 

 

分享到:
评论
2 楼 ryxxlong 2011-12-02  
lhp__2006 写道
帮我解决了一个大问题,多谢

呵呵,就是把平时开发遇到的东西放上来,能帮到人我最开心了
1 楼 lhp__2006 2011-12-02  
帮我解决了一个大问题,多谢

相关推荐

    C#将Lambda表达式转成Sql语句

    然而,在某些情况下,我们需要将这些表达式转换为实际的SQL语句,以便在数据库中执行。本文将深入探讨如何实现这一过程。 首先,我们需要了解Lambda表达式的基本结构。Lambda表达式通常以参数列表开始,后面跟着一...

    SQL 语法分析,正则表达式解析C#文件;正则表达式实现的语法分析引擎

    当一个SQL语句被提交到数据库管理系统时,系统会对其进行解析,确认其语法正确性,并将其转化为执行计划。这个过程包括词法分析、语法分析和优化等阶段。词法分析将SQL语句分解成一个个单独的符号或“标记”(tokens...

    基于Lambda表达式的SQL语句生成器SqlLink V0.1

    这个类可能包含解析Lambda表达式、生成SQL语句片段以及整合这些片段成完整SQL语句的逻辑。开发者可以通过阅读和理解`ExpressionSqlBuilder`的源代码,进一步定制SqlLink的功能,或者将其原理应用到自己的项目中。 ...

    用正则表达式提取SQL

    这类工具通常可以更准确地解析SQL语句,包括复杂的子查询、联接和窗口函数等,而不仅仅是基于正则表达式的简单匹配。它们通常提供API,允许开发者将SQL语句转换成易于处理的数据结构,以便进一步分析或执行。 总结...

    ambda表达式转SQL语句

    Lambda表达式转SQL语句类库 一、可以达到的功能 本功能类库主要提供给代码中使用Lambda表达式,后需转成SQL的条件语句这一需求 二、不能做的 1、本类库不能解析Linq语句 2、不能解析SQL中的Select部分

    JsonSQL:用SQL语句解析JSON文件

    **JsonSQL: SQL语句解析JSON文件** 在大数据处理和Web应用中,JSON(JavaScript Object Notation)格式已经成为数据交换的常见格式。然而,对于习惯使用SQL查询关系型数据库的人来说,处理JSON数据可能会觉得不太...

    HW_SQL_TOOL.rar_SQL 解析_python sql_sql解析_sql语句 python_tool

    Python有许多库支持SQL解析,例如`sqlparse`,它是一个非执行性的SQL解析库,可以解析SQL语句并返回一个解析树。 在描述中提到的"Python SQL 结构处理类"可能是一个自定义的Python类,它扩展了`sqlparse`或者其他...

    Java源代码案例 - 使用正则表达式解析sql语法树.zip

    在"Java源代码案例 - 使用正则表达式解析sql语法树.zip"这个压缩包中,我们可以推测包含了一个使用Java实现的SQL语句解析器,可能通过正则表达式解析SQL语句的语法结构。 在SQL(Structured Query Language)中,...

    Lambda表达式转SQL语句类库

    Lambda表达式转SQL语句类库 一、可以达到的功能 本功能类库主要提供给代码中使用Lambda表达式,后需转成SQL的条件语句这一需求 二、不能做的 1、本类库不能解析Linq语句 2、不能解析SQL中的Select部分

    自己编写sql语句分析工具

    而"自己编写sql语句分析工具"则是一个专为SQL解析而设计的自定义程序,它能帮助用户对各种SQL语句进行深入的分析,提取其中的关键信息。 首先,SQL解析涉及到的是SQL语法的理解和分解。一个SQL解析器通常会通过词法...

    Lambda表达式转sql

    2. **MethodCallExpression处理**:当表达式体是方法调用时,会调用`ExpressionRouter`方法来进一步解析表达式树并生成SQL语句。 3. **其他情况**:如果表达式体既不是二元运算也不是方法调用,则返回空字符串。 ##...

    sql结果还原为sql语句 python脚本

    标题中的"sql结果还原为sql语句 python脚本"指的就是这一过程,它涉及到Python编程和SQL语法的理解。 描述中提到的几个关键点如下: 1. **数值格式包含逗号**:在SQL中,数值字段可能包含逗号作为千位分隔符。在...

    sql_server 正则表达式

    ### SQL Server 2005 正则表达式的深度解析 #### 引言:正则表达式的威力 正则表达式,在SQL Server 2005中作为一种强大的文本处理工具,极大地增强了数据库处理复杂文本数据的能力。传统的T-SQL虽然在处理数据...

    c#解析SQL语句(分析语句).zip

    然而,有时我们需要对SQL语句进行更深层次的分析,例如验证SQL语法、提取查询信息或者定制查询行为,这就需要我们编写代码来解析SQL语句。 “sqlparser-master”可能是一个C#项目,该项目的目标是提供一个SQL解析器...

    DBMS.zip_C++_boost实现解析sql语句

    在解析SQL语句时,开发者需要定义一系列的正则模式,这些模式对应于SQL语句中的不同部分,例如`INSERT INTO table (columns) VALUES (values)`的各个组件。通过使用`boost::regex_match`或`boost::regex_search`函数...

    SqlParser C++实现的SQL语法解释器

    SqlParser是一款基于C++实现的SQL语法解释器,它的主要任务是解析SQL语句,将其转化为计算机可理解的形式,从而能够执行相应的数据库操作。在数据库系统中,SQL(Structured Query Language)是用于管理关系数据库的...

    泛型封装的sql语句

    为了解决这个问题,开发者通常会采用泛型(Generic)技术来封装SQL语句,提高代码的可复用性和可读性。本文将深入探讨如何利用泛型来实现灵活的SQL语句拼装,以实现“泛型封装的SQL语句”。 首先,我们要理解泛型的...

    sql语句分析源码

    - **词法分析(Lexical Analysis)**: 这是解析SQL语句的第一步,它将输入的字符串分解成一系列有意义的词法单元,如关键字、标识符、运算符等。 - **语法分析(Syntax Analysis)**: 也称为解析,此阶段将词法...

    linqer3.5 快速转换sql语句工具

    它能够解析SQL查询,并生成对应的LINQ表达式,使得开发者能够在.NET Framework 3.5及更高版本的项目中轻松地使用LINQ。LINQ(Language Integrated Query)是一种集成在编程语言中的查询技术,它提供了更直观、更简洁...

    利用antlr实现从关系代数到SQL语句的转化源程序

    然后,我们可以遍历这棵树,将每个节点转换为相应的SQL语句部分。 在实际的转换过程中,例如,关系代数的选择操作(SELECT)对应于SQL的SELECT子句,投影操作(PROJECT)对应于SQL的SELECT列表,连接操作(JOIN)...

Global site tag (gtag.js) - Google Analytics