《Oracle PL/SQL程序设计(第5版)》一一2.6 在其他语言中调用PL/SQL

2.6 在其他语言中调用PL/SQL

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 VARCHAR2
IS
  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/SQL

PL/SQL procedure successfully completed.

接下来看该如何在下面这些环境中调用这个函数:

C语言、使用Oracle的Pro*C;
Java语言,使用JDBC;
Perl,使用Perl DBI和DBD::Oracle;
PHP;
PL/SQL Server Pages。
这些例子纯粹是演示性的——比如,用户名和密码都是硬编码的,程序也仅仅是显示输出。而且,我也不会解释每一行代码。这些例子只是要让你了解,不同的语言环境中会遇到的问题模式。

2.6.1 C:使用Oracle的预编译器(Pro*C)

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 <stdio.h>
#include <string.h>

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的最好信息。

2.6.2 Java:使用JDBC

就像对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驱动,不过别担心,还没有那些编程需要用到它,除了它的名字。

2.6.3 Perl:使用Perl DBI和DBD::Oracle

Perl可以说是所有开源语言之母,也是许多系统管理社区最偏爱的。现在的版本是5.10,基本上它可以完成任何任务,可以在任何地方运行。并且它有一个漂亮的自动配置工具CPAN(Comprehensive Perl Archive Network),它是社区提供的模块的安装纽带,比如DBI(DataBase Interface)和对应的Oracle驱动DBD::Oracle。

/ File on web: callbooktitle.pl /
#!/usr/bin/perl

use strict;
use DBI qw(:sql_types);

# either make the connection or die
my $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 handle
eval {
   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语言优秀的书籍,包括在线信息http://www.perl.com(一个属于O’Reilly的站点)、http://www.perl.org和http://www.cpan.org。

2.6.4 PHP:使用Oracle扩展

如果你属于使用免费的并且广为流行的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
   // Initiate the connection to the o92 database
   $conn = OCILogon ("scott", "tiger", "o92");

   // Make parse call to Oracle, get statement identity
   $stmt = OCIParse($conn,
      "begin :res := booktitle('0-596-00180-0'); end;");

   // Show any errors
   if (!$stmt) {
      $err = OCIError();
      echo "Oops, you broke it: ".$err["message"];
      exit;
   }
   // Bind 200 characters of the variable $result to placeholder :res
   OCIBindByName($stmt, "res", &$result, 200);

   // Execute
   OCIExecute($stmt);

   // Stuff the value into the variable
   OCIResult($stmt,$result);

   // Display on stdout
   echo "$result\n";

   // Relax
   OCILogoff($conn);
?>

要在命令行运行这个命令,应该这样:

$ php callbooktitle.php
Learning Oracle PL/SQL

需要说明的是,缺省情况下这些OCI函数在PHP中是没有的,不过让系统管理员重构一个带有Oracle扩展的PHP并不困难。

更多关于PHP的信息,请看http://www.php.net或者随便一本Oracle出版的关于这个主题的图书。关于PHP针对Oracle的技巧,请访问Oracle Technology Network网站(http://otn.oracle.cm)。

2.6.5 PL/SQL Server Pages

尽管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" %>
<HTML>
  <HEAD>
    <TITLE>My favorite book about PL/SQL</TITLE>
  </HEAD>
  <BODY>
    <%= booktitle( '0-596-00180-0') %>
  </BODY>
</HTML>

<%= %>块意味着“把这一部分当作PL/SQL代码处理,然后把结果返回给页面”。如果正确的安装到Web服务器上并连接到Oracle数据库,这个页面的效果如图2-3所示。

就快速地整合数据驱动的Web站点而言,PL/SQL Server Pages提供了一个好方法,这一点也是我喜欢它的原因。

要了解更多有关PL/SQL Server Pages的信息,参看Learning Oracle PL/SQL(O’Reilly出版),也是由本书作者所著。

2.6.6 其他

你已经看到如何在SQL*Plus以及其他的一些常见环境、编程语言中使用PL/SQL了。你还可以在许多其他地方和方式使用PL/SQL。

嵌入到COBOL或者FORTRAN,并用Oracle的预编译处理。
在Visual Basic中通过某种ODBC调用。
从Ada编程语言中通过一种叫做SQL*Module的技术调用。
作为Oracle数据库的事件触发器自动执行,比如当表被更新时自动执行。
在数据库内部,利用DBMS_SCHEDULER包定期重复执行。
TimesTen数据库:Oracle公司收购的一个内存数据库产品。其内容也可以通过PL/SQL代码操作,就像在关系数据库一样。
幸运或不幸的是,我无法在本书覆盖所有的主题。

时间: 2024-12-01 20:02:05

《Oracle PL/SQL程序设计(第5版)》一一2.6 在其他语言中调用PL/SQL的相关文章

oracle 自定义函数返回一个自定义整数列,如何在下一个自定义函数中,调用上一个函数

问题描述 oracle 自定义函数返回一个自定义整数列,如何在下一个自定义函数中,调用上一个函数 ---自定义类型 create or replace type t_int is table of integer -- Create table create table TESTFUNCTION ( oid INTEGER, result INTEGER ) tablespace USERS pctfree 10 initrans 1 maxtrans 255; -- Create table

《锋利的SQL(第2版)》——1.3 Transact-SQL语言的类型

1.3 Transact-SQL语言的类型 锋利的SQL(第2版) 在介绍了SQL的起源后,来看一下Transact-SQL包括哪些语言类型.首先,为了遵循ANSI SQL标准,Transact-SQL提供了数据定义语言(Data Definition Language,DDL)语句和数据操纵语言(Data Manipulation Language,DML)语句:其次,为了增强灵活性,Transact-SQL还提供了用于编程的流控制语句和其他语句. 对于语言类型,读者仅做大致了解就可以.在实际

《交互式程序设计 第2版》一1.2 交互领域中的编程

1.2 交互领域中的编程 这本书之所以名为<交互式程序设计>,是因为我们主要关注交互设计中要用到的编程知识,也就是用编程的手段,去创造用户能直接与之交互的应用.编程有很多种,其中有些技术和思维方法更适合用于服务器和数据库,而不是交互.而本书集中讨论的东西将是你用来建立用户和应用之间沟通的知识和技能.交互设计中的一大挑战是如何在你设计的作品和用户之间建立真正的交互. 1.2.1 交互的本质 那么,"交互"到底是什么呢?我们可以把它定义为双方或多方之间的信息交换.作家及电子游戏

《R的极客理想——高级开发篇 A》一一2.4 R语言中的遗传算法

2.4 R语言中的遗传算法 问题 如何用R语言进行遗传算法的计算? 引言 人类总是在生活中摸索规律,把规律总结为经验,再把经验传给后人,让后人发现更多的规律,每一次知识的传递都是一次进化的过程,最终形成了人类的智慧.自然界的规律,让人类适者生存地活了下来,聪明的科学家又把生物进化的规律,总结成遗传算法,扩展到了更广的领域中.本节将带你走进遗传算法的世界.2.4.1 遗传算法介绍 遗传算法是一种解决最优化的搜索算法,是进化算法的一种.进化算法最初借鉴了达尔文的进化论和孟德尔的遗传学说,从生物进化的

《R的极客理想——高级开发篇 A》一一1.2 R语言中的数学计算

1.2 R语言中的数学计算 问题 如何用R语言进行数学计算? 引言 R语言是统计语言,生来就对数学有良好的支持,用R语言做数学的计算题特别方便.如果计算器中能嵌入R语言的计算函数,那么绝对是一种高科技产品.我真的把R语言当成我的计算器了!1.2.1 基本计算 R语言对数学计算有着非常好的支持,本节将完整介绍初等数学中的各种计算操作. 本节的系统环境是: Windows 7 64bit R: 3.1.1 x86_64-w64-mingw32/x64 (64-bit) 用R语言实现四则运算操作,包括

《Oracle PL/SQL程序设计(第5版)》导读

前言 Oracle PL/SQL程序设计(第5版) 全世界有成百上千万的用户和数据库管理员正在使用Oracle公司提供的软件,这些软件可以构建复杂的系统来管理海量的数据.许多Oracle软件的核心是PL/SQL--这是一款编程语言,对Oracle版本的SQL(结构化查询语言)提供了面向过程的扩展,该语言在Oracle开发工具箱(最有名的包括Forms Developer和Reports Developer)中作为编程语言使用. PL/SQL的一个显著特征是几乎可用于Oracle公司发行的所有新产

[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)

原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下) --通过知识共享树立个人品牌. 继上六篇:        [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)        [推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)        [推荐]ORA

Linux/Unix shell 调用 PL/SQL

    Linux/Unix 下除了调用SQL之外,调用PL/SQL也是DBA经常碰到的情形,下面主要通过一些示例给出如何在shell下面来调用pl/sql.     其它相关的参考:        Linux/Unix shell 脚本中调用SQL,RMAN脚本         Linux/Unix shell sql 之间传递变量 1.将pl/sql代码逐行输入到临时文件 robin@SZDB:~/dba_scripts/custom/bin> more shell_call_plsql.s

嵌入式的SQL程序设计

--嵌入式SQL程序设计 --SQL2005管理员大全 --嵌入SQL语句的应用程序叫做宿主程序,书写该程序的语言称为宿主语言. --宿主语言可以是C. C++.JAVA等.嵌入的SQL语句与交互式SQL在语法上类似 --但是嵌入式SQL在个别语句上有所扩充 --嵌入的SQL语句主要有两种类型:执行性SQL语句和说明性SQL语句.执行性SQL语句可用来 --定义 数据.查询和操纵数据库中的数据,每一执行性语句真正对数据库进行操作.说明性语句 --用来说明 通信域和SQL语句中用到的变量.说明性语