使用 WCF 服务模型在 Oracle 数据库中使用 RECORD 类型运行操作

Oracle RECORD 类型用于表示传递给 PL/SQL 函数和过程的参数中的分层信息。 适用于 Oracle 数据库的 Microsoft BizTalk 适配器将 RECORD 类型显示为复杂的 XML 类型。 在 WCF 服务模型中,RECORD 类型反序列化为强类型 .NET 类。 记录字段表示为 类上的属性。

Oracle 数据库适配器支持以下类型的 RECORD 类型:

  • 在存储过程和函数中声明为 TABLE%ROWTYPE 参数的记录类型。

  • 例如,在 PL/SQL 包中声明为 RECORD 参数的 TYPE 的记录类型, TYPE rec_type1 IS RECORD(name varchar2(100), age number(3));

  • 包含嵌套记录的记录类型。

  • 在过程或函数中显示为 IN、OUT 或 IN OUT 参数的记录类型。

  • 作为函数的 RETURN 值的记录类型。

    本主题演示如何在 WCF 服务模型中表示 RECORD 类型。 有关如何调用 Oracle 过程和函数的信息,请参阅 使用 WCF 服务模型在 Oracle 数据库中调用函数和过程

关于本主题中使用的示例

本主题中的示例使用 /SCOTT/ACCOUNT_PKG Oracle PL/SQL 包。 以下元素用于ACCOUNT_PKG。

TYPE address_rec_type IS RECORD (street customer.street%TYPE, city customer.city%TYPE, state customer.state%TYPE);  
  
FUNCTION create_account(acct IN ACCOUNT%ROWTYPE, addr IN address_rec_type) RETURN NUMBER;  
  
TYPE acctinfo_rec_type IS RECORD (acct account%ROWTYPE, address address_rec_type);  
  
FUNCTION get_accountinfo(aid NUMBER) RETURN acctinfo_rec_type;  

BizTalk 适配器包示例提供了生成此包的脚本。 有关详细信息,请参阅脚本

有关示例的详细信息,请参阅 适配器示例

WCF 服务模型中的记录类型

Oracle RECORD 类型由 Oracle 数据库适配器表示为复杂 XML 类型。 在 WCF 服务模型中,复杂 XML 类型由 类表示,此类的属性表示 Oracle RECORD 类型的字段。 表示 RECORD 类型参数的类在由 PACKAGE (限定的命名空间中生成(如果函数或过程的任意) 和 SCHEMA)。 此命名空间唯一标识 参数的函数或过程。 例如,在以下命名空间中创建 Oracle PACKAGE ACCOUNT_PKG 中CREATE_ACCOUNT过程的 RECORD 类型参数: microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.CREATE_ACCOUNT。 有关 WCF 服务模型中用于表示过程和函数中复杂类型的命名空间的详细信息,请参阅 使用 WCF 服务模型调用 Oracle 数据库中的函数和过程

虽然 RECORD 类型参数的命名空间由过程或函数确定,但为 RECORD 类型参数生成的类的名称由声明 RECORD 类型的方式确定。 下表显示如何基于声明 Oracle RECORD 类型参数的两种不同方法生成类的名称。

Oracle RECORD 类型 名称 示例
TABLE%ROWTYPE 过程或函数参数 [PARAMETER_NAME]记录 ACCTRECORD
RECORD 包参数的类型 [PACKAGE_NAME][RECORD_TYPE_NAME]记录 ACCOUNT_PKGACCTINFO_REC_TYPERECORD

[PARAMETER_NAME] = 过程或函数参数的名称;例如 ACCT。

[PACKAGE_NAME] = Oracle 包的名称。

[RECORD_TYPE_NAME] = RECORD TYPE 声明中指定的名称;例如,ACCTINFO_REC_TYPE。

以下代码显示了为两个 Oracle 函数生成的 WCF 客户端的方法签名。 /SCOTT/Package/ACCOUNT_PKG/CREATE_ACCOUNT 函数采用两个简单的 RECORD 类型 IN 参数,/SCOTT/Package/ACCOUNT_PKG/GET_ACCOUNTINFO 函数返回包含两个嵌套 RECORD 类型的 RECORD 类型参数。 Oracle 函数声明包含在代码顶部。 每个函数的参数都由唯一命名空间限定。

FUNCTION create_account(acct IN ACCOUNT%ROWTYPE, addr IN address_rec_type) RETURN NUMBER;  
FUNCTION get_accountinfo(aid NUMBER) RETURN acctinfo_rec_type;  
  
public partial class SCOTTPackageACCOUNT_PKGClient : System.ServiceModel.ClientBase<SCOTTPackageACCOUNT_PKG>, SCOTTPackageACCOUNT_PKG {  
  
    ...  
  
    public System.Nullable<decimal> CREATE_ACCOUNT(microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.CREATE_ACCOUNT.ACCTRECORD ACCT, microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.CREATE_ACCOUNT.ACCOUNT_PKGADDRESS_REC_TYPERECORD ADDR);  
  
    public microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNTINFO.ACCOUNT_PKGACCTINFO_REC_TYPERECORD GET_ACCOUNTINFO(System.Nullable<decimal> AID);  
}  

以下代码显示了为 CREATE_ACCOUNT 函数的参数生成的类: FUNCTION create_account(acct IN ACCOUNT%ROWTYPE, addr IN address_rec_type) RETURN NUMBER;

此函数具有一个用 TABLE%ROWTYPE 声明的参数,以及一个用 RECORD 包类型类型声明的参数 (TYPE acctinfo_rec_type IS RECORD (acct account%ROWTYPE, address address_rec_type);) 。

namespace microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.CREATE_ACCOUNT {  
  
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]  
    [System.Runtime.Serialization.DataContractAttribute()]  
    public partial class ACCTRECORD : object, System.Runtime.Serialization.IExtensibleDataObject {…}  
  
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]  
    [System.Runtime.Serialization.DataContractAttribute()]  
    public partial class ACCOUNT_PKGADDRESS_REC_TYPERECORD : object, System.Runtime.Serialization.IExtensibleDataObject {…}  
  
}  

简单记录类型的表示形式

以下代码演示如何在 WCF 服务模型中表示简单的 RECORD 类型。 此代码显示 ACCOUNTRECORD 类的扩展视图,该类表示 CREATE_ACCOUNT 函数中的 ACCOUNT%ROWTYPE 参数。 在此类中,记录字段 (行列) 表示为属性。

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]  
[System.Runtime.Serialization.DataContractAttribute()]  
public partial class ACCTRECORD : object, System.Runtime.Serialization.IExtensibleDataObject {  
  
    private System.Runtime.Serialization.ExtensionDataObject extensionDataField;  
  
    private System.Nullable<decimal> ACCTIDField;  
  
    private string NAMEField;  
  
    private System.Nullable<decimal> BALANCEField;  
  
    public System.Runtime.Serialization.ExtensionDataObject ExtensionData {  
        get {  
            return this.extensionDataField;  
        }  
        set {  
            this.extensionDataField = value;  
        }  
    }  
  
    [System.Runtime.Serialization.DataMemberAttribute()]  
    public System.Nullable<decimal> ACCTID {  
        get {  
            return this.ACCTIDField;  
        }  
        set {  
            this.ACCTIDField = value;  
        }  
    }  
  
    [System.Runtime.Serialization.DataMemberAttribute()]  
    public string NAME {  
        get {  
            return this.NAMEField;  
        }  
        set {  
            this.NAMEField = value;  
        }  
    }  
  
    [System.Runtime.Serialization.DataMemberAttribute(Order=2)]  
    public System.Nullable<decimal> BALANCE {  
        get {  
            return this.BALANCEField;  
        }  
        set {  
            this.BALANCEField = value;  
        }  
    }  
}  

包含嵌套记录的记录类型的表示形式

以下代码显示了包含嵌套记录的 RECORD 类型的表示形式。 此特定 RECORD 类型是) (FUNCTION get_accountinfo(aid NUMBER) RETURN acctinfo_rec_type; GET_ACCOUNTINFO函数的 RETURN 值。 ACCTINFO_REC_TYPE是一个包参数,它使用 TYPE of RECORD 构造 (TYPE acctinfo_rec_type IS RECORD (acct account%ROWTYPE, address address_rec_type);) 声明。 它包含两种嵌套的简单记录类型:TABLE%ROW 记录和一个记录记录的包类型。 这两条简单记录在与其父记录相同的命名空间中声明,并遵循预期的命名约定。

namespace microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNTINFO {  
    using System.Runtime.Serialization;  
  
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]  
    [System.Runtime.Serialization.DataContractAttribute()]  
    public partial class ACCOUNT_PKGACCTINFO_REC_TYPERECORD : object, System.Runtime.Serialization.IExtensibleDataObject {  
  
        private System.Runtime.Serialization.ExtensionDataObject extensionDataField;  
  
        private microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNTINFO.ACCTRECORD ACCTField;  
  
        private microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNTINFO.ACCOUNT_PKGADDRESS_REC_TYPERECORD ADDRESSField;  
  
        public System.Runtime.Serialization.ExtensionDataObject ExtensionData {  
            get {  
                return this.extensionDataField;  
            }  
            set {  
                this.extensionDataField = value;  
            }  
        }  
  
        [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]  
        public microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNTINFO.ACCTRECORD ACCT {  
            get {  
                return this.ACCTField;  
            }  
            set {  
                this.ACCTField = value;  
            }  
        }  
  
        [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]  
        public microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNTINFO.ACCOUNT_PKGADDRESS_REC_TYPERECORD ADDRESS {  
            get {  
                return this.ADDRESSField;  
            }  
            set {  
                this.ADDRESSField = value;  
            }  
        }  
    }  

在代码中使用 RECORD 类型

在代码中使用 RECORD 类型非常简单。 若要使用 RECORD 类型参数调用过程或函数,请创建一个或多个 RECORD 类型的实例,并将其传递给 WCF 客户端上的相应方法。 当过程或函数返回时,可以读取声明为 RECORD 类型的任何 OUT 或 IN OUT 参数或函数 RETURN 值的属性。 有关如何使用 WCF 服务模型调用过程和函数的详细信息,请参阅 使用 WCF 服务模型在 Oracle 数据库中调用函数和过程

重要

oracle RECORD 类型参数 (和函数返回) 由其函数或过程 (和包) 的命名空间限定。 这意味着,用于两个不同过程或函数的 RECORD 类型对于每个过程或函数具有不同的命名空间。 当将 RECORD 类型用于特定过程或函数时,必须确保它正确限定。 例如,用作两个不同函数的 IN 参数的 TYPE 声明) (RECORD 的包 RECORD 类型将在 WCF 客户端代码中声明两次,每个声明对应于为每个函数生成的唯一命名空间。 必须确保在传递给每个相应函数的参数上使用正确的命名空间。

在下面的示例中,使用两个简单的记录参数调用 CREATE_ACCOUNT 函数。 接下来,调用 GET_ACCOUNTINFO 函数。 此函数返回包含嵌套记录的 RECORD 类型。 返回的 RECORD 中的选定字段值将写入控制台。 此示例中省略了为 Oracle 数据库设置凭据和打开 WCF 客户端的步骤。

// Add WCF, WCF Adapter LOB SDK, and Oracle Database adapter namepaces  
using System.ServiceModel;  
using Microsoft.ServiceModel.Channels;  
using Microsoft.Adapters.OracleDB;  
  
// Include this namespace for WCF Adapter LOB SDK and Oracle Database adapter exceptions  
using Microsoft.ServiceModel.Channels.Common;  
  
…  
  
// Create the client from configuration  
using (SCOTTPackageACCOUNT_PKGClient accountPkgClient = new SCOTTPackageACCOUNT_PKGClient("OracleDBBinding_SCOTT.Package.ACCOUNT_PKG"))  
{  
  
    ...  
  
    decimal acctId;  
  
    // Create an account record  
    // Note: ACCTRECORD is defined in both namespaces so specify the definition  
    // that corresponds to the client.  
  
    microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.CREATE_ACCOUNT.ACCTRECORD acctRec =   
        new microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.CREATE_ACCOUNT.ACCTRECORD();  
  
    // Set any value for ACCTID -- new account ID is returned by CREATE_ACCOUNT  
    acctRec.ACCTID = 0;  
    acctRec.NAME = "Anton Kirilov";  
    acctRec.BALANCE = 9583;  
  
    // Create address record  
    microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.CREATE_ACCOUNT.ACCOUNT_PKGADDRESS_REC_TYPERECORD addrRec = new microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.CREATE_ACCOUNT.ACCOUNT_PKGADDRESS_REC_TYPERECORD();  
    addrRec.STREET = "234 Main St";  
    addrRec.CITY = "Boston";  
    addrRec.STATE = "MA";  
  
    // Create account  
    try  
    {  
        acctId = (decimal)accountPkgClient.CREATE_ACCOUNT(acctRec, addrRec);  
    }  
    catch (Exception ex)  
    {  
        // handle exception  
        ...  
    }  
  
    ...  
  
    // Account info record  
    microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNTINFO.ACCOUNT_PKGACCTINFO_REC_TYPERECORD acctInfo =  
    new microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNTINFO.ACCOUNT_PKGACCTINFO_REC_TYPERECORD();  
  
    // Get account info for the account just created  
    // acctInfo is returned as a nested record type  
    try  
    {  
     acctInfo = accountPkgClient.GET_ACCOUNTINFO(acctId);  
    }  
    catch (Exception ex)  
    {  
    // handle exception  
    ...  
    }  
  
    // Write the account info to the console  
    Console.WriteLine("The account info is:");  
    Console.WriteLine("Name:\t\t\t{0}", acctInfo.ACCT.NAME);  
    Console.WriteLine("Street:\t\t\t{0}", acctInfo.ADDRESS.STREET);  
    Console.WriteLine("City:\t\t\t{0}", acctInfo.ADDRESS.CITY);  
    Console.WriteLine("State:\t\t\t{0}", acctInfo.ADDRESS.STATE);  
    Console.WriteLine("Account Id:\t\t{0}", acctInfo.ACCT.ACCTID);  
    Console.WriteLine("Account Balance:\t{0:C}", acctInfo.ACCT.BALANCE);  
  
    Console.WriteLine("\nHit <RETURN> to finish");  
    Console.ReadLine();  
    }  
}  

另请参阅

使用 WCF 服务模型开发 Oracle 数据库应用程序