5.2.3 外部语言过程

5.2.3 外部语言过程

不朗读文本内容

尽管对SQL的过程化扩展非常有用,然而可惜的是这些并不被跨数据库的标准的方法所支持。即使是最基本的特性在不同数据库产品中都可能有不同的语法和语义。所以,程序员必须针对每个数据库产品学习一门新语言。还有另一种方案可以解决语言支持的问题,即在一种命令式程序设计语言中定义过程,然后从SQL查询和触发器的定义中来调用它。
SQL允许我们用一种程序设计语言定义函数,比如Java、C#、C或C++。这种方式定义的函数会比SQL中定义的函数效率更高,无法在SQL中执行的计算可以由这些函数执行。

外部过程和函数确切的语法决定于所使用的特定数据库系统
此处省略一些东西
用程序设计语言定义并在数据库系统之外编译的函数可以由数据库系统代码来加载和执行。不过这么做存在危险,那就是程序中的错误可能破坏数据库内部的结构,并且绕过数据库系统的访问-控制功能。如果数据库系统关心执行的效率胜过安全性则可以采用这种方式执行过程
关心安全性的数据库系统一般会将这些代码作为一个单独进程的一部分来执行,通过进程间通信,传入参数的值,取回结果。然而,进程间通信的时间代价相当高;在典型的CPU体系结构中,一个进程通信所需的时间可以执行数万到数十万条指令。
如果代码用Java或C#这种”安全”的语言书写,则会有第三种可能:在数据库进程本身的沙盒( sandbox)内执行代码。沙盒允许Java或C#代码访问它的内存区域,但阻止代码直接在查询执行过程的内存中做任何读操作或者更新操作,或者访问文件系统中的文件。(在如C这种语言中创建一个沙盒是不可能的,因为C语言允许通过指针不加限制地访问内存。)避免进程间通信能够大大降低函数调用的时间代价。
当今的一些数据库系统支持外部语言例程在查询执行过程中的沙盒里运行。例如, OracleIBM DB2允许Java函数作为数据库过程中的一部分运行。 Microsoft SQL Server允许过程编译成通用语言运行程序(CLR)来在数据库过程中执行;这样的过程可以用C#或Visual Basic编写。 PostgreSQL允许在PerlPythonTcl等多种语言中定义函数。