1.1 为什么在服务器中进行程序设计
开发者使用各种不同的语言进行程序开发,并且希望所编写的代码能够在任何环境下运行。当编写应用程序的时候,一些程序员会坚守这样的信条:他们认为服务端应用程序里面的处理逻辑应尽可能多地被推送到客户端。因此,我们经常能见到这样一种情况,即越来越多的应用程序会在浏览器中使用JavaScript。还有的情况则是把处理逻辑放置在中间层,然后通过应用程序服务器来处理业务规则。这些实际上都是设计应用程序的各种有效方式,那么为什么还要在数据库服务器中进行程序设计呢?
让我们从一个简单的例子开始。许多应用程序会涉及一张客户列表,这些客户的账户中有账户余额。我们将使用这个示例模式和数据:
当我们使用数据库时,最常用的方式就是使用SQL查询和数据库进行交互。如果你想从Bob的账户转移14美元到Mary的账户,你可以通过简单的SQL语句实现:
但是,你要确保Bob的账户有足够的余额(或存款)。这样的确认非常重要,因为一旦出现任何事件节点的失败,就会导致事务不被触发。因此,考虑到这一点,在应用程序开发中,以上的代码片段就会变成这样:
但是玛丽一定有账户吗?即便她没有账户,最后的UPDATE语句仍然会成功,但是却更新了0行记录。如果核对出现失败状况,那么你应该做ROLLBACK,而不是COMMIT。一旦你按照这样的流程,对所有客户端完成了转账的任务,新的需求又会出现。也许这次需求是要求把最小的可转移金额限制为5美元,这时候你就需要再次检查所有客户端中的所有代码。
所以你是否可以做些什么,使得所有这些工作更加容易管理、更加安全和更加强健?这就是服务器程序设计可以做到的事情,它可以在自动在数据库服务器上执行代码。你可以把计算、核对和数据操作全部转移到一个位于服务器上的用户定义函数里面(UDF)。这样做不仅仅保证了你只需要管理一份操作逻辑,同时也使得工作更加快捷,因为此时你不再需要在服务器与客户端之间来回穿梭。如果需要的话,你甚至只需要确保仅仅是那些必需的信息被传送到数据库之外。比如,对于大多数客户端应用程序而言,它们并不需要知道Bob账户上究竟有多少余额。大多数情况下,这些客户端应用程序仅仅需要知道账户上是否有足够的余额可用于转账,或者更简明扼要一点,它们只需要了解这次交易是否可以成功,仅此信息足矣。
使用PL/pgSQL进行完整性检查
PostgreSQL有它自己的开发语言,叫做PL/pgSQL。PL/pgSQL的主要目的就是轻松地与SQL语句集成在一起。PL是programming language的简称,意思是程序设计语言。PL仅仅是诸多可用于服务器开发语言中的一种。而pgSQL则是PostgreSQL的缩写。
与基础SQL不同,PL/pgSQL包括了程序化的元素,比如在PL/pgSQL中可以使用if /then/else语句和循环功能。你可以轻松地执行SQL语句,甚至对SQL语句的结果进行循环操作。
应用程序中所需要进行的完整性检查可以通过PL/pgSQL函数来完成。这种函数包括了3个参数:付费人的名字、收款人的名字和付费金额。这个例子同时返回这次付费的
状态:
假设你在之前并未使用过先前建议的UPDATE语句,这里提供使用这个函数的一些
例子:
该应用程序应该检查返回码,并且决定如何处理这些错误。只要程序设定了拒绝任何意外值,你就可以通过扩展这个函数,去做更多的检查工作,比如最小可转账金额,并确保这个可以避免执行。这里有3个可能会返回的错误:
为了使这些检查始终有效,你需要让所有的转账操作通过函数来执行,而不是手动使用SQL语句来改变这些值。