基于数据字典的通用查询系统(一)SQL语句的构成分析
最近做的一个项目,对口客户的负责人是一个巨难缠的老女人,在要需求时非要求“自定义查询”,要”所查即见”,刚开始可难住了我,但后来一想,不就是要在程序里拼一个sql 语句出来嘛,呵呵,拼一把,做做试试吧。
系统整体采用分层开发的方式,咱们从最开始的需求,sql 语句,一点一点的分析, 呵呵。
在msdn中,对select语句的完整定义形式如下 :
SELECT [ALL | DISTINCT] [TOP nExpr [PERCENT]] Select_List_Item [, ...]
FROM [FORCE] Table_List_Item [, ...]
[[JoinType] JOIN DatabaseName!]Table [[AS] Local_Alias]
[ON JoinCondition [AND | OR [JoinCondition | FilterCondition] ...]
[WITH (BUFFERING = lExpr)]
[WHERE JoinCondition | FilterCondition [AND | OR JoinCondition | FilterCondition] ...]
[GROUP BY Column_List_Item [, ...]] [HAVING FilterCondition [AND | OR ...]]
[UNION [ALL] SELECTCommand]
[ORDER BY Order_Item [ASC | DESC] [, ...]]
[INTO StorageDestination | TO DisplayDestination]
[PREFERENCE PreferenceName] [NOCONSOLE] [PLAIN] [NOWAIT]
现在解析一下这个定义,可以分为如下 几个部分。
1. 查询要输出的列,可以是单独的一列,也可以包含聚合函数;
2. 查询的表集合 可能是一个表,也可能是多个表,如果是多个表的话,会有join 条件进行连接。
3. Where 条件,多层的布尔表达式。
4. Group 分组。
5. 排序列。
下面对这几部分进行一一分析。来看用何种方式进行组织会比较好。
1. 输出的列
很明显,输出的列应该是一个集合,集合的每一个元素就是一个输出的列,可以是单独的数据库中的一列,也可以是加上某种聚合函数的列,如max,count,avg等,这样,我们对要输出的列有一个整体的认识,即数据库列+聚合操作,如果只输出值,可以认为是进行了一个value的聚合操作。
结论:输出的列应当是一个List<new{数据库中的列,聚合函数}> ,这里先这样简单的,直观的表示一下,呵呵,以后会进一步的设计和细化。
2. 查询 的表集
明显,要查询的表也是一个集合,但是表和表之间的关系就不是线性关系了,而是。。 呵呵,图,想像一下当年学数据库时狂画er图就知道了吧。明显的每一个表就是图的一个点,join条件是图的边,而且,这个图应该是个强连通图(不连通的情况在我们这里讨论没有意义)
3. Where 条件
对条件的处理这里要用到另一种结构,就是树,因为条件,也就是布尔表达式是一种递归的定义。
在这里,考虑两种情况,一种是由数据库中的列和比较运算符再加上用户定义的值组成的基本表达式。
即Exp àCol + compareOp + Value
另一种是由表达式和布尔条件组成复合表达式。
即 Exp àExp + boolOP +Exp
即我们要在程序设计中能把这两种语言生成的方式实现即可。
4. 分组
分组与输出列类似,但是它 和输出列是相关的,即考虑在实际应用中,分组的列一般是要输出的,并且如果有分组约束后,其他非分组列如果要输出,只能以聚合的方式输出。
这样,我们在设计时就有 必要考虑将分组列和输出列放在一起进行处理。
PS:呵呵,文笔不好,这个功能现在已经做出来了,坚持每天写一些设计的体会和感悟,和大家分享
其中主要是对各种基本数据结构和算法在实际开发中的运用,希望能有所帮助
以下初步计划如下:
三。数据库设计。
四。实体类设计
五。算法实现
有不对的地方,还请大家拍砖