<略去的代码>
要删除一个成人成员必须首先删除 Adult 表中的记录然后才能删除 Member 表中的记录。这也是事务处理的一部分,因此如何有任何错误发生则回滚所有处理。
* 删除成员
lcSQL = "Delete adult Where member_no = " + ;
AllTrim(ThisForm.txtMemberID.Value)
If SQLExec(ThisForm.nHandle, lcSQL) < 0
<略去的代码>
lcSQL = "Delete member Where member_no = " + ;
AllTrim(ThisForm.txtMemberID.Value)
If SQLExec(ThisForm.nHandle, lcSQL) < 0
<略去的代码>
如果所有删除都没有问题则提交整个事务处理且成员被删除。然后用户会看到一个空的屏幕,因此添加一条空记录到 c_member 并刷新表单显示。
问题
如何折衷地使用远程视图和 SQL pass-through?
这是更多的工作
显然,使用 SQL pass-through 比使用远程视图需要做更多的工作。视图为你做了大量的工作,维护与服务器的通信和传递 Inserts,Updates 和 Deletes。视图是易于设置和使用的。
你拥有更多的控制
你看到了两种观点的示例,使用远程视图的一个问题是在 Visual FoxPro 和后端间的通信上你只有较少的控制。对于多数据库方案,这不是一个问题。但是,在这里使用的方案中出现了问题。问题用每一个表使用一个视图得到了缓解但任然存在。当视图不能给你以所需的数据输入能力时,问题会更为突出。
当你使用 SQL pass-through 时,你可以完全控制 Visual FoxPro 与后端的通信。你构造 SQL 语句并用 SQLExec() 来发送它们到服务器。如果需要执行数据验证和检查商业规则,你可以决定在什么时候和如何做。
错误信息可以更友好
因为你在控制什么发生,并且你手动的进行数据验证,因此你可以控制错误信息。在可以预见一些事发生时,你可以截取 SQL Server 错误信息并显示给用户一个可以理解的信息。由于不可预料的事件你也会遇到 SQLExec() 失败的问题,如网络故障。对于这些,你可以决定是否分解信息或以原始方式显示它们。
一方面它提供了较少的互用性
该方法的一个问题是从某种程度上牺牲了互用性。通过 SQLExec() 发送到后端的 SQL 语句是用后端语言编写。在本示例中是 SQL Server。当转换到 Oracle 时需要重写多少代码?
虽然不同后端的基本的 Select,Insert,Update 或 Delete 格式没有太大的不同。因此这里的示例可以很容易 转移到其它后端。但是,重要的一点是取决于你使用的 SQL 语句的复杂性,这可能限制了你交换后端的能力。当然,如果应用程序是为一种后端且只用一种后端,这将不是大的问题。
另一方面它提供了更多的互用性
考虑如果你使用远程视图而且你试着删除一个没有结清借书的成员会发生什么。在服务器上定义的参照完整性会防止删除。但是,由 Oracle 送回的错误信息将与 SQL Server 送回的错误信息不同。你可以分解错误信息并将它们转换到友好的格式,但是你将不得不分解不同的后端的信息。这就限制了你的互用性,因为你不得不为不同的服务器创建分解例程。
使用 SQL pass-through 方法,你会发送一个 Select 语句到后端在 Loan 表中搜索成员。如果 Select 找到一条记录则成员不能删除。显示给用户的信息是相同的,而不论在 SQLExec() 中发送了什么。这种服务增了你的互用性,假定不同后端的 Selects,Inserts,Updates 和 Deletes 格式没有多大变化,这是一种通情达理的假设。