RETURN -1
ENDIF
ENDIF
如果有其它的事要检查, 检查代码可以接着上面的代码后面. 如果没有其它的问题, 开始一个事务处理度处理删除.
= SQLSetProp(This.nHandle, "Transactions", 2)
一个成员可能在Loanhist 表中有相关记录,每一次归还了的借书都在其中有一条记录, 或在 Reservation 表中,每一本预约的图书在其中有一条记录. 首先删除这些相关记录. 如果不这样做, 在删除成员时将会违反参照完整性. 如果其中任一删除失败则回滚事务处理.
* 删除该成员的借书历史记录
csql = "Delete loanhist Where member_no = " + ALLTRIM(csearchid)
IF sqlexec(THIS.nhandle, csql) < 0
THIS.seterror
* 回滚事务处理
= SQLROLLBACK(THIS.nhandle)
RETURN -1
ENDIF
* 删除该成员的预约记录
csql = "Delete reservation Where member_no = " + ALLTRIM(csearchid)
IF sqlexec(THIS.nhandle, csql) < 0
THIS.seterror
* 回滚事务处理
= SQLROLLBACK(THIS.nhandle)
RETURN -1
ENDIF
所有其它相关记录也将在此时删除. 一但所有相关记录删除了, 就可以删除成员了, 首先从 Adult 表然后从 Member 表中删除一个成员. Delete 必须按该顺序以保护参照完整性. 再说一遍, 如果任一删除失败, 回滚事务处理
* 删除 Adult 表中成员的记录
csql = "Delete adult Where member_no = " + ALLTRIM(csearchid)
IF sqlexec(THIS.nhandle, csql) < 0
THIS.seterror
* 回滚事务处理
= SQLROLLBACK(THIS.nhandle)
RETURN -1
ENDIF
* 删除 Member 表中成员的记录
csql = "Delete member Where member_no = " + ALLTRIM(csearchid)
IF sqlexec(THIS.nhandle, csql) < 0
THIS.seterror
* 回滚事务处理
= SQLROLLBACK(THIS.nhandle)
RETURN -1
ENDIF
如果不熟悉下一部分, 你不是没有读前面部份的这种注释就是没有睡醒. 如果成功就提交, 失败就回滚. 如果删除失败 RemoveMember 方法返回-1 否则返回1.
IF SQLCOMMIT(THIS.nhandle) < 0
THIS.seterror
* 回滚事务处理
= SQLROLLBACK(THIS.nhandle)
RETURN -1
ELSE
RETURN 1
ENDIF
保存 SQL SERVER 错误
OLE server 的 SetError 方法保存 SQL Server 错误到 LastErrDesc 属性中, 这样该属性可以在客户机上获得.
lnError = AError(laError)
This.LastErrDesc = Substr(laError[3], RAt(')',laError[3]) + 1)
OLE 服务程序的编程黑盒
文章 BKO02 包括了使用视图和 SQL pass-through 来创建两层客户服务器应用程序. 示例之一使用 SQL Server 储存过程来添加, 更新和删除成员. 该技术的一个优势是处理发生在服务器上而不是客户机上. 这不仅避免了胖客户问题也可以避免开发者弄乱数据. 例如, 如果你所做的是调用一个储存过程, 你不会忘记删除成员的相关借书历史记录.
使用三层体系与使用储存过程用术语来说是, 在编码困难程度(低)和你保留的控制等级(也属于低)上非常相似. 例如, 调用储存过程来删除一个成员的代码是
If SQLExec(ThisForm.nHandle, "Execute RemoveMember " + ;
ThisForm.txtMemberID.value) < 0
调用等价的OLE server 方法代码是
If ThisForm.oLibrary.RemoveMember(ThisForm.txtMemberID.value) < 0
在两种情况下所有的开发者都需要知道的是方法或过程的名字, 需要什么参数及返回什么. SQL Server 储存过程和OLE server 方法都成了黑盒.
某些只是管理前端的人不需要知道或关心相对于后端的中间层中有些什么. 他或她可能只想知道如何调用方法和如何知道调用是否成员. 这使得高速的后端处于高速的开发中.
胖在何处?
在来自 BKO02 SQLExec() 中的一个示例中使用了来自客户的表单来处理所有的与 SQL Server 的通信. Selects, Inserts, Updates 和 Deletes 被发送且结果按需要操作.除真正的实际数据管理外的大多数处理是在客户端完成的. 这里的风险是以胖客户终结.
在另一个来自 BKO02 SQLExec() 中的示例使用了调用位于 SQL Server 上的储存过程. 在客户机上没有做什么事, 除了管理一个每次填入一条记录的本地游标外. 数据操作和数据验证都在服务器上执行. 这里的风险是以胖服务器终结.
在本文中使用的示例中,前端除了调用 OLE server 的方法外什么也没做. 事实上, 在这个无可否认的简单的示例中, 中间层与第一个SQLExec() 惊人地相似. 实际上, 许多 OLE server 的代码取自表单MEMBEXEC.SCX.
如果所有数据验证和商业规则检查放到中间层中会不会造成一个胖中间层问题? 是不是胖问题只是上移了一个层次? 固然, OLE server 也可能超载而不能令人满意地执行它的任务. 但是, 由于它是运行在一个机器上, 因此可以比胖客户更容易通过硬件来解决. 对于一个相对内存较少的机器你可以买一个或两个以上的处理器和16 或 32 MB 以上的内存用于中间层机器, 而且这样会令人信服地看到性能问题的消失. 当然, 这仅限于机器的处理能力成为瓶颈的时候.
重要的一点是这是因为 Visual FoxPro 和 SQL Server, 如果是 Oracle 等具有数据引擎能力和语言能力的其它语言, 你可以很好的调整胖的问题. 你可以决定代码放在何处和在何处放置处理负担而且仔细的调整它们直到性能达到满意程序.
什么时候需要这样做?
要创建一个 Visual FoxPro OLE server 并不困难. 要从一个表单中或其它代码中调用一个 OLE server 的方法也不困难. 设置远程自动控制也不困难. 因此用三层体系写一个客户服务器应用程序只比使用两层体系稍稍困难些许.
因此你为什么要这样做? 什么时候你需要上移到三层体系. 毫无疑问, 性能是一个原因. 在你的客户机器动力不足时这样做, 依靠移动巨大的代码块到一个更有力的中间层盒子中, 你可以引人注目改进性能.
这有多大的可能性? Visual FoxPro 版本 5.0 的资源要求降低了这是事实, 你任然需要至少 486 加 12 MB 内存. Pentiums 加 32 MB 内存的机器目前的价格是 $2000 美元. 考虑一个公司要从大型机移开一个应用程序并用 Visual FoxPro 和 SQL Server 来重写. 他们买 100 台新机器并有一个相当快的网络. 在此情况下你可能没有认识到一个使用三层体系相对于两层体系的巨大的性能上的获益. 在这里请注意最重要的词.
可能更多的引人注目的考虑三层的理由是你可以移动你的数据给证和商业规则代码到一个地方. 假设有一个规则: 如果一个客户有 $20,000 以上的货款超过了60天没有支付则不能为该客户下新的订单. 在一个两层体系中你可以简单地在添加按钮的 Click 中编写代码并立即显示一个信息告诉用户该客户不能下订单. 用户喜欢这样且每人都高兴.
假定该规则修改了并把限制提高到 $30,000. 有多少客户机器上的代码需要修改? 你是不是需要重新生成APP 或 EXE 文件并重新分发它? 这是一个相当大的负担很大的花费. 你可以设计系统为把商业规则保存在某个地方的一个元数据表中. 如果是这样, 对于你来说没有什么问题. 如果不是, 对于一个看来如此简单的修改有着大量的工作要做.
但是如果商业规则是在一个 OLE server 上, 修改是相当地简单. 你可以修改代码并重新编译一个 EXE. 没有客户机器需要修改. 该规则将在 EXE 运行时生效, 且维护的工作量要少得多了.
即使一个远程 OLE server 稍稍减少了全部性能你可能任然会使用它以利用它减少维护的负担.
结论
OLE server 中间层方法提供了一系列诱人的好处. 它运行在一个单一的机器上的事实允许你运行你的验证和商业规则在一个强有力的机器上而不会打破你的预算. 你可以购买一个超级机器来增强每一个客户机.
当它来到时, 在需要修改验证或商业规则时你只需要修改中间层. 你可以修改 Visual FoxPro 代码和重新生成 OLE server. 每一个客户都会自动使用新的规则, 因为这些规则是在相同的位置上.分发修改的问题和保证所有客户使用相同代码问题, 以及更新, 规则等问题都变得令人注目的简单了.
① 凡本网注明稿件来源为"原创"的所有文字、图片和音视频稿件,版权均属本网所有。任何媒体、网站或个人转载、链接转贴或以其他方式复制发表时必须注明"稿件来源:我考网",违者本网将依法追究责任;
② 本网部分稿件来源于网络,任何单位或个人认为我考网发布的内容可能涉嫌侵犯其合法权益,应该及时向我考网书面反馈,并提供身份证明、权属证明及详细侵权情况证明,我考网在收到上述法律文件后,将会尽快移除被控侵权内容。