我眼中的Visual FoxPro 8.0(二)2007-05-09 boe (三)全新的“连接”Visual FoxPro 8在异构数据库编程的增强,更直接一些就是对 SQL Server支持的改进。我觉得,至少体现在两个方面:一个是通过 CursorAdapter 对象提供一种比远程视图更加灵活、更容易编程的 Cursor 管理对象;另一个是在原有的基础上革新了“连接”的概念,使得“连接”处理更加独立、“连接”管理更加方便、“连接”更容易被共享!前面我们已经对CursorAdapter作了分析,接下来就让我们看看“连接”的变化吧!1、DBC 中的“连接”对象和“连接句柄”以前我介绍 Visual FoxPro 里的“连接”时,经常强调这样两个概念:DBC 中的“连接”对象(组件)和“连接句柄”。DBC 中的“连接”对象(组件)只是一种定义,描述怎样通过 ODBC 连接到数据源;“连接句柄”是实例化的“连接”对象(组件)。我们可以通过USE远程视图或者使用 SQLCONNECT() 打开“连接”对象,得到“连接句柄”。另两种方式,可以更加直接的方式得到“连接句柄”,就是在SQLSTRINGCONNECT()中直接使用连接字符串;还有就是SQLCONNECT()中直接引用操作系统(ODBC.INI)中的DSN 定义。这里需要注意的是,这两种方式跳过了 DBC 的“连接”对象(组件),使得Visual FoxPro 不容易管理它们。Visual FoxPro 8 以前,“连接句柄”并不独立,主要是“远程视图”自己管理“连接句柄”,其他“远程视图”或者 SPT需要共享“连接句柄”是非常麻烦的,“远程视图”之间共享“连接句柄”,需要定义所有参与共享的“远程视图”的ShareConnection属性为.T.;SPT 要取得“远程视图”的“连接句柄”必须在USE“远程视图”以后,使用 CURSORGETPROP() 函数取得“连接句柄”。除了麻烦以外,还有不能实现的功能,如先期已经存在的“连接句柄”不能被“远程视图”共享。这一切都是因为“远程视图”太过“自主”所致!2、Statement Handle Vs. “连接句柄”为了解决“远程视图”的“独断专行”,Visual FoxPro 8 提出了“远程视图”设计时与运行时分离的思路,引入了一个新的关于“连接”的概念―― Statement Handle,同时 Visual FoxPro 8 保留了“连接句柄”概念。从 Visual FoxPro 8 开始开发者直接处理的任何Handle 都是 Statement Handle,而不是“连接句柄”了!进一步讲,“远程视图”使用的是 Statement Handle、SPT使用的也是 Statement Handle。也就是说,我们在 DBC 里建立、设计“远程视图”使用的连接与“远程视图”运行时的连接可以没有任何关系,我们可以在 USE 语句中即时指定“远程视图”将要使用的Statement Handle。这就是 Visual FoxPro 8 针对 C/S 编程中“连接”的一个改进。
Statement Handle 与“连接句柄”的关系。我以为:
- “连接句柄”是 Statement Handle 的基础,Statement Handle 是“连接句柄”的衍生;
- 真正与数据源连接的是“连接句柄”,而不是Statement Handle;开发人员直接操作的是Statement Handle,而不是“连接句柄”;
- 某一条“连接句柄”可以衍生出一条或者多条Statement Handle,而某一条 Statement Handle只可能对应到一条确定的“连接句柄”;
- 新建一条连接的实例,将(可能)产生一条新的“连接句柄”和一条新的Statement Handle,这条Statement Handle对应到这条“连接句柄”;
- 新建一条连接的实例,如果当前Visual FoxPro 系统中已经存在一条符合以下两个要求的“连接句柄”,这两个要求分别是:允许被共享,并且“连接”语句的定义一致(可以认为来源于 DBC 的同一个“连接”对象)。这时不会生成一条新的“连接句柄”(不会再与数据源建立一条新的 ODBC 通道),而是直接由已经存在的“连接句柄”衍生出一条新的Statement Handle,这条Statement Handle共享原先那条“连接句柄”。
- 当一条“连接句柄”衍生的 Statement Handle 全部被释放了以后,“连接句柄”才会释放。
- 根据一条可共享的“连接句柄”可以衍生出多条Statement Handle。
- 的“连接句柄”一定是根据 DBC中“连接”对象(组件)所创建的。使用连接字符串(SQLSTRINGCONNECT())或者直接引用操作系统 DSN 创建的“连接句柄”只能衍生出惟一条Statement Handle。这是因为,Visual FoxPro 判断不同 Statement Handle是否“同源”的依据是 DBC 的“连接”对象(组件),而不是 ADO.NET那样根据连接字符串定义区分。
从上面的表述中,我们发现:因为“连接句柄”与 Statement Handle 的关系是“一对多”的,如果拿 SQL Server 作为数据源,我们可以建立一条“连接句柄”、根据它衍生多条Statement Handle,实际上连接到 SQL Server 的只有一条连接,而应用程序中却可以有多条Statement Handle,这就是一种新概念的“连接共享”!3、一个实例

让我们通过下面的例子来具体了解一下Statement Handle与“连接句柄”。设DBC里有一个“连接对象”(组件),名为 “CD1”,连接到SQL Server 数据库。
Con1=SQLCONNECT("CD1",.T.)
连接成功,返回 Con1=1。Con1 表示 Statement Handle ,以后就可以通过这个Con1 打开“远程视图”或者执行 SPT 命令;由于此时系统中并没有存在“连接句柄”,所以同时产生一条“连接句柄”,需要获取“连接句柄”可以通过:
ODBC1=SQLGETPROP(Con1,"ODBChdbc")
我这里ODBC1=49551184。这个ODBC1并不需要开发人员关心,也不需要通过程序维护。
接着,我们就根据 ODBC1衍生其他的Statement Handle:
Con2=SQLCONNECT("CD1",.T.)
返回 Con2=2。Con2 表示 Statement Handle,以后就可以通过这个Con2 打开“远程视图”或者执行 SPT 命令;我们获取 Con2 的“连接句柄”看一看:
ODBC2=SQLGETPROP(Con2,"ODBChdbc")
我这里ODBC2=49551184。说明,ODBC1和 ODBC2 是一个东西,衍生了两条Statement Handle。虽然,编程中,我们可以使用 Con1或者 Con2,但是真正与 SQL Server 的连接只有一条,就是“连接句柄”。
接着,我们需要关闭“连接句柄”衍生的所有的Statement Handle,才能真正断开Visual FoxPro 与 SQL Server 之间的连接。
SQLDISCONNECT(Con1)
SQLDISCONNECT(Con2)
通过这个简单的例子,也许有利于我们来理解新的“连接”。虽然,Visual FoxPro 8在“连接”这一块动了大手术,但是这对于旧的系统影响并不是很大,因为编程接口并没有变化,Visual FoxPro 只是在更底层的地方加了一层概念。话要说回来,如果要真正用好这个新特性,还是应该改变一下编程思路。4、 “连接”体系更改的原因也许,我们还会有这样的疑问:Visual FoxPro 8为什么要加入 Statement Handle 这样的概念,按照以前的做法直接使用“连接句柄”在各处传递,不是也能够实现“连接共享”吗?笔者认为这是面向对象化编程的需要、多层开发的需要。整个构架系统的思路就是更好的面向对象化编程、更好的多层开发,所以才有了结构化错误处理、CursorAdapter和此处的 Statement Handle。上文,我使用了“衍生”一词,从词义理解一定是用“连接句柄”显式生成新的Statement Handle,但是从实例代码中大家看到了,产生 Con1和 Con2 的代码是一样的。从理论上讲,就是:Visual FoxPro 能够自行管理 “连接句柄”,开发人员只需要也只应该处理相应的 Statement Handle,而并不需要关心由同一“连接句柄”衍生出的其他Statement Handle。这样对于模块化开发是很有好处的,同时也解决了“共享连接”问题。关于“连接”的话题谈的差不多了,不过有一个问题是需要注意的:一个“连接句柄”可以衍生多个Statement Handle,在开发中,如果有一个 Statement Handle进入了事务处理状态,这时所有相关的Statement Handle也进入了事务处理状态,这因为 SQL Server 的事务是根据真实的连接区分的——由于某一条Statement Handle 的要求,使得“连接句柄”进入了事务状态,理所当然的该条“连接句柄”衍生的所有Statement Handle也一起进入了同一个事务处理。(当然,不是由已经进入事务状态的“连接句柄”衍生的Statement Handle,不会进入事务状态。)终于完成了我在 Visual FoxPro 8 中的“首航”,细细揣摩一些 Visual FoxPro 8的新特征,我深深体会到一个指导思想贯穿着整个 Visual FoxPro 8的构架,这个思想就是:支持更完美的对象封装。由此推断:用 Visual FoxPro 8 进行对象化编程、多层开发一定比以前更加容易、更加灵活!