VFP作为一个功能强大的数据库应用系统开发工具,在国内已流行多年,并拥有一大批忠实用户。利用VFP提供的功能完善、操作简便的集成开发环境,可以快速创建出各种功能完善的可视化应用程序。其中的查询、视图设计器,更是能让用户无需熟悉SQL语句便可轻松地创建所要的查询或视图,令人爱不释手。然而,在实际使用中,我们发现VFP的视图设计器存在着一个十分严重的缺陷,使稍微复杂一些的视图无法用设计器直接创建。
一、问题的提出:
假设有一数据库JXSJ,包含如下5张表:
xs.dbf(学生表): cj.dbf(成绩表): kc.dbf(课程表):
字段 |
含义 |
|
字段 |
含义 |
|
字段 |
含义 |
xh |
学号 |
|
xh |
学号 |
|
kcdh |
课程代号 |
Xm |
姓名 |
|
Kcdh |
课程代号 |
|
Kcmc |
课程名称 |
xb |
性别 |
|
cj |
成绩 |
|
kss |
课时数 |
zydh |
专业代号 |
|
|
|
|
|
|
Xdh |
系代号 |
|
|
|
|
|
|
xi.dbf(系表): zy.dbf(专业表):
字段 |
含义 |
|
字段 |
含义 |
xdh |
系代号 |
|
zydh |
专业代号 |
Xmc |
系名称 |
|
Zymc |
专业名称 |
|
|
|
|
|
各表之间的关系如下:
现要求:建立一个包含每个学生的姓名、所学课程、成绩、学生所在系、所属专业的视图。
使用视图设计器,按常规步骤进行创建,你会发现:得到的视图中,总是出现某一字段或几个字段全是同一个值,如:“专业”字段出现全是“微机应用”。这显然是一种不正常现象。
上述情况你可能也遇到过。一开始,以为是表之间的连接顺序不对,因为错误的连接次序也会导致出现重复值。可是无论你怎样选择字段、怎样调整连接次序,总是得不到正确结果。真是百思不得其解!
静下心来,细细研究其对应的SELECT-SQL语句,终于发现了一个秘密:VFP的视图设计器的确存在着严重缺陷,而并非是我的操作方法有什么错误!
二、分析原因
现在按上述要求建立视图,选择输出字段如下:
表之间的联接情况见下图:
设计完毕后,运行查询,现出下面的结果:
其中zymc(专业名称)一列全部是“微机应用”!这个结果显然是错误的。
查看对应的SQL-SELECT语句如下:
SELECT Cj.xh,Xs.xm,Xi.ximing,Zy.zymc,Kc.kcm,Cj.cj ;
FROM jxsj!kc INNER JOIN jxsj!cj ;
INNER JOIN jxsj!xs ;
INNER JOIN jxsj!xi ;
INNER JOIN jxsj!zy ;
ON Xs.zydh = Zy.zydh ;
ON Xi.xidh = Xs.xidh ;
ON Xs.xh = Cj.xh ;
ON Kc.kcdh = Cj.kcdh ;
ORDER BY Cj.xh
其中,子句
jxsj!kc INNER JOIN jxsj!cj ;
INNER JOIN jxsj!xs ;
INNER JOIN jxsj!xi ;
INNER JOIN jxsj!zy ;
ON Xs.zydh = Zy.Zydh ;;
ON Xi.xidh = Xs.xidh ;
ON Xs.xh = Cj.xh ;
ON Kc.kcdh = Cj.Kcdh ;
的含义是:
①KC表按条件Kc.kcdh = Cj.Kcdh 内部连接CJ表;
②CJ表表按条件Xs.xh = Cj.Xh 内部连接XS表;
③XS表按条件Xi.xidh = Xs.Xidh 内部连接XI表;
④XS表表按条件Xs.zydh = Zy.Zydh 内部连接ZY表;
这四个INNER JOIN层层嵌套,即①中套②,②中套③,③中套④。
但实际是前3步嵌套是正确的,而第4步嵌套则是完全错误的!
原因是:从 KC CJ XS XI 这4张不同的表是一个衔接一个地以“串联”方式联接的,而第4步从XS ZY,与第3 步XS XI 是一种“并联”方式。
即出现了这样一种联接:
KC CJ XS XI
ZY
事实证明:只要出现上述“串联”中带“并联”的联接方式,那么,由视图设计器生成的视图总是错误的!
当然,前面已提到,错误的连接方式也可能会造成某个字段出现重复值。
例如:在只有XI XS CJ KC 四张表的情况下,如果在视图设计器中以如下次序连接,同样会产生字段值重复现象:
CJ KC XS XI XS CJ
正确的连接方式应该是:
CJ KC XS CJ XS XI
或
KC CJ CJ XS XS XI
即按照一个固定的方向,“承前启后”地连接下去。
但这种由于连接不正确而造成的结果错误,毕竟只是小问题,可以通过调整连接顺序来解决,不属于本文讨论的范围。
三、补救办法
仔细研究SQL-SELECT语句的语法格式,发现如果将INNER JOIN子句改写为如下形式,即可完全避免上述不正常现象:
jxsj!kc INNER JOIN jxsj!cj ON Kc.kcdh = Cj.kcdh ;
INNER JOIN jxsj!xs ON Xs.xh = Cj.xh ;
INNER JOIN jxsj!xi ON Xi.xidh = Xs.xidh ;
INNER JOIN jxsj!zy ON Xs.zydh = Zy.zydh ;
即将4个条件分别写在对应的INNER JOIN后面。
上述小小改动,看似举手之劳,但由于视图设计器中的SELECT-SQL是只读的,无法直接修改,因而导致你将无法直接用视图设计器建立上述视图。而只能用
Create SQL View 命令来创建,或者干脆凡是用到视图的地方都改为SELECT语句。
令人奇怪的是:VFP5.0中的这个错误,在VFP 6.0中仍没有得到改正,这对广大VFP的忠实用户来说,不能不说是件遗憾的事。
|