惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
J
Java Code Geeks
IT之家
IT之家
Last Week in AI
Last Week in AI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
B
Blog RSS Feed
P
Proofpoint News Feed
博客园 - Franky
MongoDB | Blog
MongoDB | Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 【当耐特】
Microsoft Security Blog
Microsoft Security Blog
I
InfoQ
B
Blog
Stack Overflow Blog
Stack Overflow Blog
Martin Fowler
Martin Fowler
博客园 - 聂微东
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Apple Machine Learning Research
Apple Machine Learning Research
大猫的无限游戏
大猫的无限游戏
U
Unit 42
aimingoo的专栏
aimingoo的专栏

博客园 - Hussar

中国高科技产业三大困境 [转贴]架构设计贵在务实 源代码,让.NET 平台上可以运行Python [原创]struct和class区别的背后 [翻译]部署Microsoft .NET Framework Version 3.0(含下载) 怎样作有效推论的策略 C#实现的18位身份证格式转换 [入门系列]面向服务的体系结构概述(第一部分) [入门系列]如何构建 SOA 系统 [入门系列]SOA 与其他技术的关系 [入门系列]构成 SOA 的技术 [入门系列]面向服务的体系结构可以做什么? [入门系列]什么是面向服务的体系结构(SOA)? From TechEd: Putting the user back in SOA 架构设计师与 SOA (第二部分) 架构设计师与SOA(第一部分) 关于SOA的7个问题 .NET程序员面试的题一部 [原创]C#应用访问Microsoft SQL Server 2005分析服务
在 Oracle 产品中使用 .NET 存储过程
Hussar · 2006-05-14 · via 博客园 - Hussar

转贴前言
现在Oracle 10g2 和IBM最新的DB2都支持.NET的存储过程了。剩下好像只有Sybase了。

前言:
对于 .NET 开发人员而言,针对 Windows 的 Oracle 数据库 10g 第 2 版中最激动人心的特性之一是,能够通过Oracle Database Extensions for .NET使用选择的 .NET 语言来实施存储过程。

掌握使用 Oracle 产品进行 .NET 应用程序开发这一部分中,介绍了如何在应用程序中使用 .NET 存储过程的分步方法。 您将了解到如何支持 .NET 存储过程,如何安装和配置 Oracle 数据库来支持 .NET 存储过程,如何开发和部署 .NET 存储过程,以及如何调试 .NET 存储过程。

支持体系结构

PL/SQL 存储过程和函数在与 Oracle 数据库相同的进程中运行,并且存储在 Oracle 内部。 另一方面,.NET 存储过程在外部进程中运行,.NET 代码将被编译成“.NET 程序集”,后者是存储在文件系统中的动态链接库 (DLL) 文件(通常存储在与数据库相同的机器上)。 .NET 程序集将被加载到一个名为 extproc.exe 的“CLR 宿主”外部进程中并在其中运行,该进程由名为

<OracleHomeName>ClrAgnt

的 Windows 服务衍生而来。 当执行 .NET 存储过程调用时,Oracle 将与这个外部进程通信,传入参数并检索结果。 这种通信将由 Oracle 多线程代理体系结构来处理。 对于最终用户而言,.NET 存储过程调用看起来与任何其他类型的存储过程调用没有什么区别。 实际上,您可以从能够调用 PL/SQL 或 Java 存储过程的任何环境中调用 .NET 存储过程。

安装和配置:

如果您使用的是 Oracle 数据库 10g Express 版本,那么,.NET 存储过程将自动进行安装和配置 — 无需额外的配置。 但是,在标准版和企业版中,默认情况下不会安装和配置 .NET 存储过程。 以下是使这些安装正常运行的基本指导:

  1. 下载针对 Windows 平台的 Oracle 数据库 10.2 或更高版本。(注意: 其他任何平台都不支持 .NET 存储过程!)
  2. 运行安装程序 (setup.exe)。
  3. 选择 Advanced Installation,然后选择 Custom。
  4. 请务必和其他的安装选择一起勾上 Oracle Database Extensions for .NET。
  5. 当安装完成时,运行 Database Configuration Assistant(从开始菜单中选择 Oracle > Configuration > Migration Tools)。
  6. 在配置助手中,选择配置 Oracle Database Extensions for .NET 数据库选项。
  7. 当完成时,请确保 <OracleHome>ClrAgent 服务已启动。
  8. 下载 Oracle Developer Tools for Visual Studio .NET 版本 10.2 或更高版本,并进行安装。 需要该版本才能部署 .NET 存储过程。

开发和部署 .NET 存储过程

您将开发和部署一个简单但功能齐全的 .NET 存储过程,该过程将根据国家/地区代码来检索国家/地区名称。 您将使用 HR 示例模式中的 Countries 表,Oracle 数据库 10g 第 2 版包含了该示例模式。Countries 表结构如下:

SQL> desc countries
Name           Null?Type
-------------- -------- ------------
COUNTRY_ID     NOT NULL CHAR(2)
COUNTRY_NAME            VARCHAR2(40)
REGION_ID               NUMBER

要创建存储过程,请使用 Visual Studio .NET 2003 中的一种新项目类型 — "Oracle Project":

图 1

创建一个新的 Oracle 项目(名称为 "MyStoredProcedure"),您将看到项目向导已经添加了一条到 Oracle Data Provider for .NET 程序集的引用,并将 ODP.NET 命名空间添加到了类文件中。 Visual Studio .NET 2003 开发环境应与下图类似:

图 2

您用您的代码来替换由项目向导创建的 StoredProcedure1 过程,以从 Countries 表中获取国家/地区名称。 您的新过程将接收国家/地区 ID 作为一个整型参数,并将国家/地区名称作为一个字符串值返回。 在开发过程时要注意的关键一点是 .NET 存储过程中的代码与您在独立的程序中使用的代码几乎相同。 事实上,唯一的区别是用来建立与数据库的连接的连接字符串。 下面是完整的代码:

using System;
using System.Data;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
namespace MyStoredProcedure
{
/// 
/// Summary description for Class1.
/// 
public class Class1
{
public static string GetCountryName(string CountryID)
{
// used to return the country name
string CountryName = "";
// Get a connection to the db
// context connection is used in a stored procedure
OracleConnection con = new OracleConnection();
con.ConnectionString = "context connection=true";
con.Open();
// Create command and parameter objects
OracleCommand cmd = con.CreateCommand();
cmd.CommandText = "select country_name from countries where country_id = :1";
cmd.Parameters.Add(":1", OracleDbType.Varchar2, CountryID, ParameterDirection.Input);
// get a data reader
OracleDataReader rdr = cmd.ExecuteReader();
// get the country name from the data reader
if(rdr.Read())
{
CountryName = rdr.GetString(0);
}
// clean up objects
rdr.Close();
cmd.Dispose();
// Return the country name
return CountryName;
}
}
}

同样,除了特殊的连接字符串之外,这些代码和您要在客户端应用程序中包含的代码是相同的。 通过上下文

connection=true

,您将指定代码使用调用它的进程的连接,并且您只可以在存储过程内部指定上下文

connection=true

OracleConnection

有一个名为

IsAvailable

的新属性,您可以用它来确定代码是否在存储过程的上下文中运行。 如果

IsAvailable

属性返回

true

,那么代码是在存储过程的上下文中运行的。 否则该属性将返回

false

。 根据代码是在存储过程中运行还是在独立的应用程序中运行,您可以轻松地使用该属性来构建连接字符串。 这使您只需进行少许修改就可重用代码。

在部署存储过程之前,您必须首先构建该项目。 因为您将在部署过程之后对其进行调试,因此请务必对项目执行调试编译。 在构建项目之后,您将利用部署向导来将其部署至数据库。 这时,您必须使用到数据库的 SYSDBA 连接,以部署存储过程。 如果在 Oracle Developer Tools for Visual Studio .NET 内部的 Data Connection 节点中没有提供 SYSDBA 连接,那么您可通过该向导创建一个。

要部署存储过程,请从 Visual Studio .NET 2003 菜单栏中选择 Build→ Deploy Solution。 这将启动部署向导:

图 3

阅读完向导第一步中的信息之后,请单击 Next。 然后,向导将提示您选择要使用的数据库连接。 如果您还没有定义数据库连接,那么请单击 New Connection 按钮。 否则,请选择您想使用支持 SYSDBA 的连接。

图 4

选择了要使用的数据库连接之后,请单击 Next 按钮。 您可在向导中的这一步中选择希望使用的部署选项。 因为您还没有部署该过程,所以请接受默认选项来部署该程序集,并在数据库中创建存储过程包装程序:

图 5

单击 Next 按钮继续。 指定将在部署项目之后使用的 DLL 的名称:

图 6

接受由向导提供的默认值,并单击 Next,指定要将项目部署至其中的目录:

图 7

只需单击 Next,接受默认值。 这将把项目部署至 %ORACLE_HOME%\bin\clr 目录。 下一步中,您可以指定要部署哪些方法、方法应被部署到哪个模式中、数据库中的方法名、安全级别和类型映射:

图 8

要正确地部署项目,请选择

GetCountryName

方法,选择 HR 作为模式,接受提供的数据库方法名,并接受提供的安全级别。

以下是三种可用的安全级别:

  • 安全 (Safe): 只允许访问数据库资源。 不允许访问诸如本地文件系统或网络连接之类的资源
  • 外部 (External): 允许访问诸如文件系统和网络连接之类的资源
  • 不安全 (Unsafe): 无限制

要指定数据库和 .NET 数据类型之间的输入和输出参数映射,请单击 Parameter Type Mapping 按钮:

图 9

向导将根据代码中的 .NET 类型来选择值。 如果这些值正确,即可接受它们。

部署向导中的最后一步概述了选择的选项,并允许您查看要执行的操作的脚本。 要执行实际的部署,请单击 Finish 按钮。 一旦部署完成,您可通过查看部署目录来验证是否已创建文件:

C:\>dir c:\oracle\10.2\database\bin\clr
Volume in drive C is Local Disk
Volume Serial Number is 94FF-538C
Directory of c:\oracle\10.2\database\bin\clr
09/10/2005  07:18 PM    <DIR>          .
09/10/2005  07:18 PM    <DIR>          ..
09/10/2005  07:18 PM            16,384 MyStoredProcedure.dll
1 File(s)         16,384 bytes
2 Dir(s)  26,689,114,112 bytes free

您可以使用 SQL*Plus 来验证过程是否被正确部署以及是否运行正常:

SQL*Plus: Release 10.2.0.1.0 - Production on Sat Sep 10 19:21:47 2005
Copyright (c) 1982, 2005, Oracle.All rights reserved.
SQL> connect hr
Enter password:
Connected.
SQL> select GetCountryName('FR') from dual;
GETCOUNTRYNAME('FR')
---------------------------------------------------------------------
France
1 row selected.

您还可以使用 Oracle Developer Tools for Visual Studio .NET 来运行该过程。 要执行这一操作,请展开 HR 连接,展开 Functions 节点,选择 GETCOUNTRYNAME 函数,单击右键,并选择 Run

图 10

这将生成 Run Function 对话框:

图 11

输入 FR 并单击 OK 按钮。 这将在 Visual Studio .NET 2003 IDE 中生成以下结果窗口:

图 12

调试 .NET 存储过程

要从 Visual Studio .NET 2003 IDE 内部调试已部署的存储过程,您需要将程序调试数据库 (Program Debug Database) 文件复制到部署 DLL 的目录中。 将 MyStoredProcedure.pdb 文件复制到 %ORACLE_HOME%\bin\clr 目录中:

C:\>dir c:\oracle\10.2\database\bin\clr
Volume in drive C is Local Disk
Volume Serial Number is 94FF-538C
Directory of c:\oracle\10.2\database\bin\clr
09/10/2005  07:32 PM    <DIR>          .
09/10/2005  07:32 PM    <DIR>          ..
09/10/2005  07:18 PM            16,384 MyStoredProcedure.dll
09/10/2005  06:44 PM            11,776 MyStoredProcedure.pdb
2 File(s)         28,160 bytes
2 Dir(s)  26,681,720,832 bytes free

该目录现在包含 DLL 和 .pdb 文件。

因为 DLL 文件是由 extproc.exe 进程加载的,因此您必须在 Visual Studio .NET 2003 中附加到该进程上去,以对其进行调试。 因为在前一步中执行了存储过程,因此 extproc.exe 进程应当正在运行。 但是,如果还没有执行该过程,那么该进程就没有处于运行中。 因此,在试图调试代码之前,应当通过 SQL*Plus 或 Oracle Developer Tools for Visual Studio .NET 来执行该过程。

要调试该过程,请在源代码中设置断点,如下所示:

图 13

接下来,请从 Visual Studio .NET 2003 菜单栏中选择 Tools → Debug Processes。 这将生成 Process 对话框。 向下滚动 Available Processes 的列表,并选择 extproc.exe

图 14

单击 Attach 按钮,附加到 extproc.exe 进程上去。 这将生成 Attach to Process 对话框:

图 15

因为您开发的过程是一个 .NET 过程,所以请确保选中了 Common Language Runtime 复选框,并取消选择其他所有的复选框。 单击 OK 按钮,关闭“Attach to Process”对话框,并返回至“Processes”对话框。 在“Process”对话框中单击 Close 按钮,开始调试过程。

要启动进程并触发断点,您必须调用过程。 在 Visual Studio 的 Oracle Query 窗口中或从 SQL*Plus 会话中调用过程,如下所示:

SQL> select GetCountryName('FR') from dual;

注意: 如果 .NET 过程的断点是在 Visual Studio 的同一个例程中设置的,那么请不要使用 Oracle Explorer“Run”菜单项来启动该过程。 这将由于死锁而挂起 Visual Studio。

该调用操作将调用过程,SQL*Plus 将看起来是挂起状态。 不过,该过程将在 Visual Studio .NET 2003 中停止在断点处。

图 16

您现在可以象通常处理独立代码一样来调试过程。

在调试附加进程与调试独立代码之间有一个重要的区别。 因为 extproc.exe 进程是在开发环境外部的,因此进程可能终止或被破坏,而调试环境检测不到这种情况。 在这种情况下,您将看到如下所示的错误:

SQL> select GetCountryName('FR') from dual
*
ERROR at line 1:
ORA-28576: lost RPC connection to external procedure agent
ORA-06512: at SYS.DBMS_CLR, line 234
ORA-06512: at HR.GETCOUNTRYNAME, line 7

如果您遇到这种错误,请重新执行对存储过程的调用,这一般将重启 extproc.exe 进程。 其他的故障诊断技巧包括:关闭和重连调用程序的连接以及破坏 extproc.exe 并重启 CLR 服务(强迫重新衍生 extproc.exe)。

结论

在这篇介绍性的文章中,我们着眼于针对 Windows 平台的 Oracle 数据库 10g 第 2 版中对 .NET 存储过程的支持,并介绍了如何支持 .NET 存储过程,如何配置 Oracle 网络连接组件,如何开发和部署 .NET 存储过程,以及如何调试部署的过程。 您现在应当已经能够在自己的环境中开发和部署 .NET 存储过程了。

 来源:
http://www.oracle.com/technology/global/cn/pub/articles/mastering_dotnet_oracle/williams_sps.html