REF CURSOR 是 Oracle PL/SQL 數據類型,代表 Oracle 資料庫中結果集的指標。 Microsoft BizTalk Adapter for Oracle Database 支援程式、函式和套件中的 REF CURSOR 參數。 REF CURSOR 參數可以是強型別或弱型別,視它們在程式或函式中宣告的方式而定。 如需 Oracle 資料庫配接器如何表示 REF CURSOR 參數的詳細說明,請參閱 REF CURSORS 的訊息架構。下表摘要說明 WCF 服務模型中如何呈現 REF CURSOR 參數。
| 參數方向 | 強型別 REF 游標 | 弱類型 REF CURSOR |
|---|---|---|
| 在內 | string [PARAM_NAME]包含 PL/SQL 區塊的字串。 PL/SQL 區塊必須藉由執行 「OPEN FOR SELECT」 語句或叫用函式或程式,傳回已開啟的 REF CURSOR。 問號 (?) 表示傳回 參數的 REF CURSOR 位置。 例如,「BEGIN OPEN ? FOR SELECT * FROM MY_TABLE; END", 或 "BEGIN MY_PROC(PARM1, ?, PARM2); END;"。 |
與強類型相同 |
| 出口 | out [PROC_NS].[PARAM_NAME]RECORD[] [PARAM_NAME]強型別的記錄集。 |
out [GENERIC_NS].GenRecordRow[] [PARAM_NAME]弱類型化的泛型記錄集。 |
| IN OUT | IN OUT REF CURSOR 參數會分割成 IN 和 OUT 參數。 IN 參數會附加方法簽章中的 「_IN」,以區別其與 OUT 參數。 OUT 參數由強型別的記錄集來表示。string [PARAM_NAME]_INout [PROC_NS].[PARAM_NAME]RECORD[] [PARAM_NAME] |
IN OUT REF CURSOR 參數會分割成 IN 和 OUT 參數。 IN 參數會附加 「_IN」,以區分它與 OUT 參數。 OUT 參數由弱類型的記錄集表示。string [PARAM_NAME]_INout [GENERIC_NS].GenRecordRow[] [PARAM_NAME] |
[PARAM_NAME] = Oracle 資料庫上函數或程序定義中的參數名稱;例如,MYREFCURSOR。
[PROC_NS] = 用於包含封裝、程式或函式參數的唯一命名空間;例如,“microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACTIVITY”。
[GENERIC_NS] = 定義泛型記錄集的命名空間“microsoft.lobservices.oracledb._2007._03”。
關於本主題中使用的範例
本主題中的範例會使用 /SCOTT/Package/ACCOUNT_PKG Oracle PACKAGE。 下列程序是從 ACCOUNT_PKG 使用的:
PROCEDURE get_activity(inrecs IN SYS_REFCURSOR, status OUT NUMBER, inoutrecs IN OUT activity_ref_type, outrecs OUT SYS_REFCURSOR);
SDK 範例會附帶一個用於產生此套件的腳本。 如需 SDK 範例的詳細資訊,請參閱 SDK 中的範例。
WCF 服務模型中的 REF CURSOR 參數
下列範例顯示針對 /SCOTT/Package/ACCOUNT_PKG/GET_ACTIVITY 程式所產生的類別和 WCF 用戶端。 此程序具有弱型別的 IN 和 OUT REF CURSOR 參數,以及強型別的 IN OUT REF CURSOR 參數。
以下是在 WCF 用戶端中生成用以調用 GET_ACTIVITY 的方法簽名。
public System.Nullable<decimal> GET_ACTIVITY(string INRECS, string INOUTRECS_IN, out microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACTIVITY.INOUTRECSRECORD[] INOUTRECS, out microsoft.lobservices.oracledb._2007._03.GenRecordRow[] OUTRECS);
在 GET_ACTIVITY 方法中,IN OUT 參數 INOUTRECS 會分割成兩個參數:
INOUTRECS_IN是代表 IN REF CURSOR 參數的字串。
INOUTRECS 是一個強類型記錄集,代表 OUT REF CURSOR 參數。
弱型別 OUT 參數 OUTRECS 會以一般記錄集表示。 弱型別 IN 參數 INRECS 會以字串表示。
Strongly-Typed 輸出參考游標參數
強型別的 OUT (或 IN OUT) REF CURSOR 參數會根據 SCHEMA、PACKAGE 以及所使用的程序或函式名稱,在唯一的命名空間中生成。 針對 /SCOTT/Package/ACCOUNT_PKG/GET_ACTIVITY 程式,此命名空間為 microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACTIVITY。 類別名稱是通過將參數名稱附加「RECORD」形成,而類別則由代表 Oracle 欄位的屬性組成。 以下顯示類別的一部分,代表針對 INOUTRECS REF CURSOR 參數產生的強類型記錄。
namespace microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACTIVITY {
using System.Runtime.Serialization;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute()]
public partial class INOUTRECSRECORD : object, System.Runtime.Serialization.IExtensibleDataObject {
...
private System.Nullable<decimal> TIDField;
...
[System.Runtime.Serialization.DataMemberAttribute()]
public System.Nullable<decimal> TID {
get {
return this.TIDField;
}
set {
this.TIDField = value;
}
}
...
}
}
Weakly-Typed OUT REF CURSOR 參數
弱類型 OUT(或 IN OUT)REF CURSOR 參數由一般記錄類別表示。 一律會在相同的命名空間中產生泛型記錄集,不論函式或程序為何,都會使用相同的類別名稱。 下列程式碼顯示泛型記錄類別 microsoft.lobservices.oracledb._2007._03.GenRecordRow,代表 OUTRECS OUT SYS_REFCURSOR 參數(弱類型)的記錄。
namespace microsoft.lobservices.oracledb._2007._03 {
using System.Runtime.Serialization;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute()]
public partial class GenRecordRow : object, System.Runtime.Serialization.IExtensibleDataObject {
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
private microsoft.lobservices.oracledb._2007._03.GenRecordColumn[] GenRecordColumnField;
public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
get {
return this.extensionDataField;
}
set {
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public microsoft.lobservices.oracledb._2007._03.GenRecordColumn[] GenRecordColumn {
get {
return this.GenRecordColumnField;
}
set {
this.GenRecordColumnField = value;
}
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute()]
public partial class GenRecordColumn : object, System.Runtime.Serialization.IExtensibleDataObject {
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
private string ColumnNameField;
private string ColumnValueField;
private string ColumnTypeField;
public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
get {
return this.extensionDataField;
}
set {
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true, EmitDefaultValue=false)]
public string ColumnName {
get {
return this.ColumnNameField;
}
set {
this.ColumnNameField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)]
public string ColumnValue {
get {
return this.ColumnValueField;
}
set {
this.ColumnValueField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true, EmitDefaultValue=false, Order=2)]
public string ColumnType {
get {
return this.ColumnTypeField;
}
set {
this.ColumnTypeField = value;
}
}
}
}
搭配 WCF 用戶端使用 REF CURSOR 參數
若要使用 WCF 用戶端叫用具有 REF CURSOR 參數的程式或函式,請執行下列動作:
針對包含 PL/SQL 區塊的每個 IN 或 IN OUT REF CURSOR 參數傳遞字串,以開啟 REF CURSOR。 此區塊可以執行 OPEN FOR SELECT 語句,或叫用在 OUT 參數中傳回已開啟 REF CURSOR 的函式或程式。
當程序或函式傳回時,對於 OUT 或 IN OUT REF CURSOR 參數所傳回的記錄集中的數據進行操作。 記錄集將是弱型別 REF CURSOR 參數的一般記錄集,或是強型別 REF CURSOR 參數的強型別記錄集。
如需如何使用 WCF 服務模型叫用程式和函式的詳細資訊,請參閱 使用 WCF 服務模型叫用 Oracle 資料庫中的函式和程式。
下列範例會呼叫 GET_ACTIVITY 程式。 它示範指定 IN REF CURSOR 參數的兩種方式:
針對 IN REF CURSOR 參數,會指定 OPEN FOR SELECT 語句來傳回 ACCOUNT 100001的活動。
針對 IN OUT REF CURSOR 參數,會叫用 /SCOTT/Package/ACCOUNT_PKG/GET_ALL_ACTIVITY 程式。 此程式會開啟 REF CURSOR,其中包含 ACCOUNTACTIVITY 數據表中的所有活動,並將它當做 OUT 參數傳回。
此範例也會示範如何從傳回強型別與弱型別 REF CURSOR 參數的記錄集讀取資料。
using System;
using System.Collections.Generic;
using System.Text;
// Add WCF, WCF LOB Adapter SDK, and Oracle Database adapter namepaces
using System.ServiceModel;
using Microsoft.ServiceModel.Channels;
using Microsoft.Adapters.OracleDB;
// Include this namespace for WCF LOB Adapter SDK and Oracle Database adapter exceptions
using Microsoft.ServiceModel.Channels.Common;
// namespaces for strongly-typed and weakly typed REF CURSOR records
using GET_ACTIVITYns = microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACTIVITY;
using GENERICns = microsoft.lobservices.oracledb._2007._03;
// In this sample, INRECS is opened by using an OPEN FOR statement, and
// INOUTRECS_IN is opened by calling the GET_ALL_ACTIVITY procedure on Oracle.
namespace OracleRefCursorsSM
{
class Program
{
static void Main(string[] args)
{
// Create the client
SCOTTPackageACCOUNT_PKGClient accountPkgClient =
new SCOTTPackageACCOUNT_PKGClient("OracleDBBinding_SCOTT.Package.ACCOUNT_PKG");
// Set credentials
accountPkgClient.ClientCredentials.UserName.UserName = "SCOTT";
accountPkgClient.ClientCredentials.UserName.Password = "TIGER";
try
{
GET_ACTIVITYns.INOUTRECSRECORD[] strongCursor;
GENERICns.GenRecordRow[] weakCursor;
Console.WriteLine("Opening client");
// Open the client
accountPkgClient.Open();
Console.WriteLine("Invoking ACCOUNT_PKG.GET_ACTIVITY");
// Get ACCOUNTACTIVITY records
// The IN REF CURSOR is set to all activity for account 100001
// The input part of the IN OUT ref cursor calls GET_ALL_ACTIVITY
// The weakly-typed OUT REF CURSOR parameter returns a list of activity for account 100001
// The strongly-typed IN OUT REF CURSOR parameter returns a list of all activity
string inRecsString = "BEGIN OPEN ? FOR SELECT * FROM ACCOUNTACTIVITY WHERE ACCOUNT=100001; END;";
string inoutRecsString = "BEGIN ACCOUNT_PKG.GET_ALL_ACTIVITY(?); END;";
accountPkgClient.GET_ACTIVITY(
inRecsString,
inoutRecsString,
out strongCursor,
out weakCursor);
// Display strong ref cursor (all activity)
Console.WriteLine("\nList of all activity returned (strong ref cursor)");
Console.WriteLine("Tx Id\tAccount\tAmount\tDate\t\t\tDescription");
for (int i = 0; i < strongCursor.Length; i++)
{
Console.WriteLine("{0}\t{1}\t{2:C}\t{3}\t{4}",strongCursor[i].TID,
strongCursor[i].ACCOUNT,
strongCursor[i].AMOUNT,
strongCursor[1].TRANSDATE,
strongCursor[i].DESCRIPTION);
}
// Display weak ref cursor (account 100001)
Console.WriteLine("\nList of activity for account 100001 returned (weak ref cursor)");
Console.WriteLine("Tx Id\tAmount\tDate\t\t\tDescription");
for (int i = 0; i < weakCursor.Length; i++)
{
Console.WriteLine("{0}\t{1:C}\t{2}\t{3}", weakCursor[i].GenRecordColumn[0].ColumnValue,
weakCursor[i].GenRecordColumn[2].ColumnValue,
weakCursor[i].GenRecordColumn[4].ColumnValue,
weakCursor[i].GenRecordColumn[3].ColumnValue);
}
Console.WriteLine("\nHit <RETURN> to finish");
Console.ReadLine();
}
catch (TargetSystemException tex)
{
Console.WriteLine("Exception occurred on the Oracle Database");
Console.WriteLine(tex.InnerException.Message);
}
catch (ConnectionException cex)
{
Console.WriteLine("Exception occurred connecting to the Oracle Database");
Console.WriteLine(cex.InnerException.Message);
}
catch (Exception ex)
{
Console.WriteLine("Exception is: " + ex.Message);
if (ex.InnerException != null)
{
Console.WriteLine("Inner Exception is: " + ex.InnerException.Message);
}
throw ex;
}
finally
{
// Close the client
accountPkgClient.Close();
}
}
}
}