本文共 6248 字,大约阅读时间需要 20 分钟。
本节书摘来自异步社区出版社《Oracle PL/SQL程序设计(第5版)》一书中的第2章,第2.6节,作者:【美】Steven Feuerstein , Bill Pribyl,更多章节内容可以访问云栖社区“异步社区”公众号查看。
Oracle PL/SQL程序设计(第5版)
总有一天,你会在从C、Java、Perl、PHP或其他语言中调用PL/SQL。虽然这是一个很合理的需求,如果你曾经做过跨语言的开发工作,你一定熟知要把各种语言专有的数据类型糅合在一起─尤其是那些复合数据类型,比如数组、记录或者对象类型─的复杂性,更不用说不同的参数语法或者厂商对所谓“标准”应用编程接口(API)的扩展,比如微软的ODBC(Open Database Connectivity)。我会用几个简短的例子演示一下如何从外部调用PL/SQL程序。假设我写一个PL/SQL函数,这个函数接收一个字符串类型的ISBN参数,然后返回对应的图书名称:
/* File on web: booktitle.fun */FUNCTION booktitle (isbn_in IN VARCHAR2) RETURN VARCHAR2IS l_title books.title%TYPE; CURSOR icur IS SELECT title FROM books WHERE isbn = isbn_in;BEGIN OPEN icur; FETCH icur INTO l_title; CLOSE icur; RETURN l_title;END;
如果是在SQL/Plus中,我可以用好几种方法来调用它,最短代码的方式可能是这样的:
SQL> EXEC DBMS_OUTPUT.PUT_LINE(booktitle('0-596-00180-0'))Learning Oracle PL/SQLPL/SQL procedure successfully completed.
接下来看该如何在下面这些环境中调用这个函数:
C语言、使用Oracle的Pro*C;
Java语言,使用JDBC;Perl,使用Perl DBI和DBD::Oracle;PHP;PL/SQL Server Pages。这些例子纯粹是演示性的——比如,用户名和密码都是硬编码的,程序也仅仅是显示输出。而且,我也不会解释每一行代码。这些例子只是要让你了解,不同的语言环境中会遇到的问题模式。Oracle至少提供了两种不同的C语言接口:一个叫做OCI(Oracle Call Interface),这主要是科学家的领域,另一个就是ProC。OCI提供了上百个函数,就算只是一个SQL查询请求,也需要编写像打开、解析、绑定、定义、执行、提取结果等这些低层次的代码。即便是最简单的OCI程序也需要近200行长的代码,我还是演示一个ProC的例子吧。Pro*C是一个预编译的技术,你可以编写一个同时包括C、SQL、PL/SQL的混合源代码文件。通过在Oracle的proc程序中运行下面代码,输出的是C代码。
/* File on web: callbooktitle.pc */#include#include EXEC SQL BEGIN DECLARE SECTION; VARCHAR uid[20]; VARCHAR pwd[20]; VARCHAR isbn[15]; VARCHAR btitle[400];EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE SQLCA.H;int sqlerror();int main(){ /* VARCHARs actually become a struct of a char array and a length */ strcpy((char *)uid.arr,"scott"); uid.len = (short) strlen((char *)uid.arr); strcpy((char *)pwd.arr,"tiger"); pwd.len = (short) strlen((char *)pwd.arr); /* this is a cross between an exception and a goto */ EXEC SQL WHENEVER SQLERROR DO sqlerror(); /* connect and then execute the function */ EXEC SQL CONNECT :uid IDENTIFIED BY :pwd; EXEC SQL EXECUTE BEGIN :btitle := booktitle('0-596-00180-0'); END; END-EXEC; /* show me the money */ printf("%s\n", btitle.arr); /* Disconnect from ORACLE. */ EXEC SQL COMMIT WORK RELEASE; exit(0);}sqlerror(){ EXEC SQL WHENEVER SQLERROR CONTINUE; printf("\n% .70s \n", sqlca.sqlerrm.sqlerrmc); EXEC SQL ROLLBACK WORK RELEASE; exit(1);}
正像你看到的那样,ProC并不是一个追求纯粹的语言家所支持的,你也不想和这种方式生成的C代码搅合在一起。然而,很多企业发现ProC(或者像Pro*Cobol等Oracle支持的语言)是位于像Visual Basic(太笨重和缓慢的一个语言)和OCI(太难了)中间的一个比较合适的选择。
从Oracle自己的文档中,可以找到关于Pro*C的最好信息。
就像对C语言一样,Oracle对于Java开发也提供了几种连接到数据库的方法。其中嵌入的SQL方法叫做SQLJ,和Oracle的其他预编译技术类似,是调试器友好的。另一种更流行的和专门针对Java的技术叫做JDBC,名字其实不能代表任何东西,不过经常被解释成“Java Database Connectivity”。
/* File on web: Book.java */import java.sql.*;public class Book{ public static void main(String[] args) throws SQLException { //初始化驱动,然后尝试创建一个连接 DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver ()); Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:o92", "scott", "tiger"); // prepareCall中使用了ANSI92的“call”语法 CallableStatement cstmt = conn.prepareCall("{? = call booktitle(?)}"); // 设置绑定变量和参数 cstmt.registerOutParameter(1, Types.VARCHAR); cstmt.setString(2, "0-596-00180-0"); // 现在执行语句,得到结果,关闭连接,打印结果 cstmt.executeUpdate(); String bookTitle = cstmt.getString(1); conn.close(); System.out.println(bookTitle); }}
这个例子使用的是瘦驱动(Thin Driver),这种驱动除了有些通讯性能上有些开销外,还是有很好的兼容性和易于安装的(在Java的库中已经包括了所有网络协议)。另一种方法是使用OCI驱动,不过别担心,还没有那些编程需要用到它,除了它的名字。
Perl可以说是所有开源语言之母,也是许多系统管理社区最偏爱的。现在的版本是5.10,基本上它可以完成任何任务,可以在任何地方运行。并且它有一个漂亮的自动配置工具CPAN(Comprehensive Perl Archive Network),它是社区提供的模块的安装纽带,比如DBI(DataBase Interface)和对应的Oracle驱动DBD::Oracle。
/* File on web: callbooktitle.pl */#!/usr/bin/perluse strict;use DBI qw(:sql_types);# either make the connection or diemy $dbh = DBI->connect( 'dbi:Oracle:o92', 'scott', 'tiger', { RaiseError => 1, AutoCommit => 0 }) || die "Database connection not made: $DBI::errstr";my $retval;# make parse call to Oracle, get statement handleeval { my $func = $dbh->prepare(q{ BEGIN :retval := booktitle(isbn_in => :bind1); END; });# bind the parameters and execute $func->bind_param(":bind1", "0-596-00180-0"); $func->bind_param_inout(":retval", \$retval, SQL_VARCHAR); $func->execute;};if( $@ ) { warn "Execution of stored procedure failed: $DBI::errstr\n"; $dbh->rollback;} else { print "Stored procedure returned: $retval\n";}# don't forget to disconnect$dbh->disconnect;
Perl属于那种为了追求简单,不惜牺牲阅读性的语言。Perl不是一个特别快速和小巧的语言,不过还是有些编译版本至少能够解决速度的问题。
更多关于Perl和Oracle的信息,可以参考Alligator Descartes的Programming the Perl DBI(O’Reilly出品)。还有许多关于Perl语言优秀的书籍,包括在线信息(一个属于O’Reilly的站点)、和。
如果你属于使用免费的并且广为流行的Web服务器Apache一族,你可能也会乐意使用同样免费并且广为流行的编程语言PHP。PHP除了可以用于构建动态网页,也可以用于构建GUI应用,或者命令行方式的程序。正如你所期待的,Oracle是可以和PHP一起工作的数据库之一。实际上Oracle公司是Zend的合作伙伴,以提供一个带有PHP的Oracle数据库发行版1。
下面的例子使用了PHP中被称作OCI8的函数家族,不要让这个名字中的8把你愚弄了,其实它可以和从Oracle 7到Oracle 11g的各个版本一起工作。
/* File on web: callbooktitle.php */
要在命令行运行这个命令,应该这样:
**$ php callbooktitle.php
Learning Oracle PL/SQL**需要说明的是,缺省情况下这些OCI函数在PHP中是没有的,不过让系统管理员重构一个带有Oracle扩展的PHP并不困难。更多关于PHP的信息,请看或者随便一本Oracle出版的关于这个主题的图书。关于PHP针对Oracle的技巧,请访问Oracle Technology Network网站()。
尽管PL/SQL Server Pages(PSP)环境是Oracle专有的,我觉得还是应该提一下,因为这是一个快速的运行Web页面的方法。PSP是另一种预编译技术,它让你可以在HTML页面中嵌入PL/SQL代码。
/* File on web: favorite_plsql_book.psp */<%@ page language="PL/SQL" %><%@ plsql procedure="favorite_plsql_book" %>My favorite book about PL/SQL <%= booktitle( '0-596-00180-0') %>
<%= %>块意味着“把这一部分当作PL/SQL代码处理,然后把结果返回给页面”。如果正确的安装到Web服务器上并连接到Oracle数据库,这个页面的效果如图2-3所示。
就快速地整合数据驱动的Web站点而言,PL/SQL Server Pages提供了一个好方法,这一点也是我喜欢它的原因。
要了解更多有关PL/SQL Server Pages的信息,参看Learning Oracle PL/SQL(O’Reilly出版),也是由本书作者所著。
你已经看到如何在SQL*Plus以及其他的一些常见环境、编程语言中使用PL/SQL了。你还可以在许多其他地方和方式使用PL/SQL。
嵌入到COBOL或者FORTRAN,并用Oracle的预编译处理。
在Visual Basic中通过某种ODBC调用。从Ada编程语言中通过一种叫做SQL*Module的技术调用。作为Oracle数据库的事件触发器自动执行,比如当表被更新时自动执行。在数据库内部,利用DBMS_SCHEDULER包定期重复执行。TimesTen数据库:Oracle公司收购的一个内存数据库产品。其内容也可以通过PL/SQL代码操作,就像在关系数据库一样。幸运或不幸的是,我无法在本书覆盖所有的主题。转载地址:http://mzdoa.baihongyu.com/