WCF 서비스 모델을 사용하여 Oracle Database에서 REF CURSORS를 사용하여 작업 실행
REF CURSOR는 Oracle 데이터베이스의 결과 집합에 대한 포인터를 나타내는 Oracle PL/SQL 데이터 형식입니다. Microsoft BizTalk Adapter for Oracle Database는 프로시저, 함수 및 패키지에서 REF CURSOR 매개 변수를 지원합니다. REF CURSOR 매개 변수는 프로시저 또는 함수에서 선언되는 방법에 따라 강력한 형식이거나 약한 형식일 수 있습니다. ORACLE 데이터베이스 어댑터에서 REF CURSOR 매개 변수를 나타내는 방법에 대한 자세한 설명은 REF CURSORS에 대한 메시지 스키마를 참조하세요. 다음 표에서는 REF CURSOR 매개 변수가 WCF 서비스 모델에 표시되는 방법을 요약합니다.
매개 변수 방향 | 강력한 형식의 REF CURSOR | 약한 형식의 REF CURSOR |
---|---|---|
IN | 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); 끝;". |
강력한 형식과 동일 |
OUT | out [PROC_NS].[PARAM_NAME]RECORD[] [PARAM_NAME] 강력한 형식의 레코드 집합입니다. |
out [GENERIC_NS].GenRecordRow[] [PARAM_NAME] 약한 형식의 제네릭 레코드 집합입니다. |
IN OUT | IN OUT REF CURSOR 매개 변수는 IN 및 OUT 매개 변수로 분할됩니다. IN 매개 변수는 OUT 매개 변수와 구분하기 위해 메서드 서명에 "_IN"이 추가됩니다. OUT 매개 변수는 강력한 형식의 레코드 집합으로 표시됩니다.string [PARAM_NAME]_IN out [PROC_NS].[PARAM_NAME]RECORD[] [PARAM_NAME] |
IN OUT REF CURSOR 매개 변수는 IN 및 OUT 매개 변수로 분할됩니다. IN 매개 변수에는 OUT 매개 변수와 구분하기 위해 "_IN"이 추가됩니다. OUT 매개 변수는 약한 형식의 레코드 집합으로 표시됩니다.string [PARAM_NAME]_IN out [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 매개 변수가 있습니다.
다음은 GET_ACTIVITY 호출하기 위해 WCF 클라이언트에서 생성되는 메서드의 서명입니다.
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는 제네릭 레코드 집합으로 표시됩니다. 약한 형식의 INRECS 매개 변수는 문자열로 표시됩니다.
REF CURSOR 매개 변수 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;
}
}
...
}
}
REF CURSOR 매개 변수 Weakly-Typed
약한 형식의 OUT(또는 IN OUT) REF CURSOR 매개 변수는 제네릭 레코드 클래스로 표시됩니다. 제네릭 레코드 집합은 함수 또는 프로시저에 관계없이 항상 동일한 네임스페이스와 동일한 클래스 이름으로 생성됩니다. 다음 코드에서는 OUTRECS OUT SYS_REFCURSOR 매개 변수(약한 형식)의 레코드를 나타내는 제네릭 레코드 클래스인 microsoft.lobservices.oracledb._2007._03.GenRecordRow를 보여 줍니다.
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 Database에서 함수 및 프로시저 호출을 참조하세요.
다음 예제에서는 GET_ACTIVITY 프로시저를 호출합니다. IN REF CURSOR 매개 변수를 지정하는 두 가지 방법을 모두 보여 줍니다.
IN REF CURSOR 매개 변수의 경우 ACCOUNT 100001 대한 작업을 반환하도록 OPEN FOR SELECT 문이 지정됩니다.
IN OUT REF CURSOR 매개 변수의 경우 /SCOTT/Package/ACCOUNT_PKG/GET_ALL_ACTIVITY 프로시저가 호출됩니다. 이 절차에서는 ACCOUNTACTIVITY 테이블의 모든 활동을 포함하는 REF CURSOR를 열고 OUT 매개 변수로 반환합니다.
또한 이 예제에서는 강력한 형식의 REF CURSOR 매개 변수와 약한 형식의 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();
}
}
}
}