Aufrufen von Funktionen und Prozeduren in Oracle Database mithilfe des WCF-Dienstmodells
Der Microsoft BizTalk-Adapter für Oracle Database zeigt Prozeduren, Funktionen und Pakete als Vorgänge an. Im WCF-Dienstmodell werden diese Vorgänge als Methoden auf einem WCF-Client dargestellt. Das WCF-Dienstmodell und der Oracle Database-Adapter:
Unterstützungsfunktionen. Der RETURN-Wert der Oracle-Funktion wird als Rückgabewert der WCF-Clientmethode angezeigt. Oracle-Parameter werden als Parameter (mit der entsprechenden Richtung, wie unten definiert) für die WCF-Clientmethode angezeigt.
Supportverfahren. Der erste OUT-Parameter der Oracle-Prozedur wird als Rückgabewert der WCF-Clientmethode angezeigt. Alle anderen Oracle-Parameter werden als Parameter (mit der entsprechenden Richtung, wie unten definiert) für die WCF-Clientmethode angezeigt.
Unterstützung von Oracle-Paketen. Der Name des Vorgangs und der Namespace seiner Parametertypen werden durch den Paketnamen qualifiziert.
Unterstützung überladener Funktionen und Prozeduren.
Unterstützung von IN-, OUT- und IN OUT-Parametern für grundlegende Oracle-Datentypen für Prozeduren und Funktionen. OUT-Parameter werden als out-Parameter in der WCF-Clientmethode angezeigt, und IN OUT-Parameter werden als Ref-Parameter angezeigt.
Unterstützt DIE REF CURSOR-Parameter IN, OUT und IN OUT für Prozeduren und Funktionen sowie RÜCKGABEwerte der Funktion. Weitere Informationen finden Sie unter Ausführen von Vorgängen mit REF CURSORS in Oracle Database mithilfe des WCF-Dienstmodells.
Unterstützt DIE IN-, OUT- und IN OUT RECORD-Typparameter für Prozeduren und Funktionen sowie RÜCKGABEwerte der Funktion. Weitere Informationen finden Sie unter Ausführen von Vorgängen mit RECORD-Typen in Oracle Database mithilfe des WCF-Dienstmodells.
Informationen zu den in diesem Thema verwendeten Beispielen
In den Beispielen in diesem Thema wird die überladene Prozedur /SCOTT/Package/ACCOUNT_PKG/GET_ACCOUNT verwendet. Dieses Verfahren liest einen Datensatz aus der SCOTT/ACCOUNT-Tabelle basierend auf einer Konto-ID oder einem Kontonamen. Ein Skript zum Generieren dieser Prozedur und Tabelle wird mit den SDK-Beispielen bereitgestellt. Weitere Informationen zu den SDK-Beispielen finden Sie unter Beispiele im SDK.
Die WCF-Clientklasse
Die folgende Tabelle zeigt den Namen des WCF-Clients und die Methode, die für Prozeduren, Funktionen und Pakete generiert wurde, die vom Oracle Database-Adapter angezeigt werden. Sofern eine Funktion oder Prozedur nicht überladen ist, wird ein einzelner WCF-Client verwendet, um alle Funktionen in einem Schema, alle Prozeduren in einem Schema oder alle Funktionen und Prozeduren in einem Paket aufzurufen.
Oracle-Artefakt | Name des WCF-Clientvorgangs | Beispiel |
---|---|---|
Prozedur | [SCHEMA] ProcedureClient. [PROC_NAME] | SCOTTProcedureClient.MYPROC |
Funktion | [SCHEMA] FunctionClient. [FUNC_NAME] | SCOTTProcedureClient.MYFUNC |
Paket (Prozedur oder Funktion) | [SCHEMA] Package[PACKAGE_NAME]Client. [PROC_NAME oder FUNC_NAME] | SCOTTPackageMYPACKAGEClient.MYPROC |
[SCHEMA] = Sammlung von Oracle-Artefakten; z. B. SCOTT.
[PROC_NAME] = Der Name einer Oracle-Prozedur; beispiel: MYPROC.
[FUNC_NAME] = Der Name einer Oracle-Funktion; z. B. MYFUNC.
[PACKAGE_NAME] = Der Name eines Oracle-Pakets.
Der Oracle Database-Adapter stellt Oracle RECORD-Typparameter und Rückgabewerte sowie die von REF CURSOR-Parametern zurückgegebenen Resultsets als komplexe XML-Typen dar, die die Zeilendaten (oder Felder) eines Oracle-Datensatzes enthalten. Im WCF-Dienstmodell wird jeder dieser XML-Typen als .NET-Klasse dargestellt. Die Eigenschaften der -Klasse stellen die Felder des RECORD-Typs oder des REF CURSOR-Resultsets dar. Oracle RECORD-Typen werden immer als stark typisierte .NET-Klassen dargestellt. Ein REF CURSOR-Resultset kann jedoch entweder als stark typisierte oder schwach typisierte Datensätze dargestellt werden, je nachdem, ob der REF CURSOR selbst als stark oder schwach typisiert deklariert ist. Die Klassen, die REF CURSOR- oder RECORD-Typparameter (oder Rückgabewerte) darstellen, werden in einem eindeutigen Namespace basierend auf der Prozedur, Funktion oder dem Paket generiert. In der folgenden Tabelle sind diese Namespaces aufgeführt.
Oracle-Artefakt | Namespace | Beispiel |
---|---|---|
Prozedur | [BASE_NS]. [SCHEMA]. Verfahren. [PROC_NAME] | microsoft.lobservices.oracledb._2007._03.SCOTT. Procedure.MYPROC |
Funktion | [BASE_NS]. [SCHEMA]. Funktion. [FUNC_NAME] | microsoft.lobservices.oracledb._2007._03.SCOTT. Function.MYFUNC |
Paket (Prozedur) | [BASE_NS]. [SCHEMA]. Paket. [PACKAGE_NAME]. [PROC_NAME] | microsoft.lobservices.oracledb._2007._03.SCOTT. Package.MYPACKAGE.MYPROC |
Paket (Funktion) | [BASE_NS]. [SCHEMA]. Paket. [PACKAGE_NAME]. [FUNC_NAME] | microsoft.lobservices.oracledb._2007._03.SCOTT. Package.MYPACKAGE.MYFUNC |
Generischer Datensatzsatz (schwach typisiert) | [BASE_NS] | microsoft.lobservices.oracledb._2007._03 |
[BASE_NS] = Der Basisadapternamespace; microsoft.lobservices.oracledb._2007._03.
[SCHEMA] = Sammlung von Oracle-Artefakten; z. B. SCOTT.
[PROC_NAME] = Der Name einer Oracle-Prozedur; Zum Beispiel; MYPROC.
[FUNC_NAME] = Der Name einer Oracle-Funktion; z. B. MYFUNC.
[PACKAGE_NAME] = Der Name eines Oracle-Pakets.
Informationen zur Verwendung dieser Namespaces für RECORD-Parameter finden Sie unter Ausführen von Vorgängen mit RECORD-Typen in Oracle-Datenbank mithilfe des WCF-Dienstmodells. Informationen zur Verwendung dieser Namespaces für REF CURSOR-Parameter finden Sie unter Ausführen von Vorgängen mit REF CURSORS in Oracle Database mithilfe des WCF-Dienstmodells.
Im Allgemeinen werden die Oracle-Parameter und -Rückgabewerte in der WCF-Clientmethode wie folgt zugeordnet:
Oracle IN-Parameter werden .NET-Parametern (Eingabeparametern) zugeordnet.
Oracle OUT-Parameter werden . NET-Outparametern zugeordnet.
Oracle IN OUT-Parameter werden . NET-Refparametern zugeordnet.
Funktion RETURN-Werte werden dem Rückgabewert der Methode zugeordnet.
Es gibt jedoch zwei wichtige Ausnahmen:
Oracle IN OUT REF CURSOR-Parameter werden in eine Eingabezeichenfolge und einen Ausgabedatensatz (out) aufgeteilt. Dies liegt daran, dass der Oracle Database-Adapter IN REF CUSROR-Parameter als Zeichenfolgen und OUT REF CURSOR-Parameter als komplexe Typen (Datensatzsätze) darstellt. Diese können nicht in einem einzelnen Parameter kombiniert werden.
Der erste OUT-Parameter in einer Oracle-Prozedur wird dem Rückgabewert der WCF-Clientmethode zugeordnet. Dies ist standardmäßiges WCF-Verhalten.
Das folgende Beispiel zeigt einen Teil einer einfachen Oracle-Prozedur (geladen im SCOTT-Schema) und die Signatur der WCF-Clientmethode, die generiert wird, um sie aufzurufen. Die Oracle-Prozedur verfügt über drei IN-Parameter, drei IN OUT-Parameter und drei OUT-Parameter. Die WCF-Clientmethode zuordnen jedoch keinen Parameter für den ersten OUT-Parameter. Stattdessen wird sie dem Rückgabewert der Methode zugeordnet.
CREATE or REPLACE PROCEDURE Sample_Procedure
(
INNUMBER IN NUMBER,
INVARCHAR IN VARCHAR2,
INDATE IN DATE,
INOUTNUMBER IN OUT NUMBER,
INOUTVARCHAR IN OUT VARCHAR,
INOUTDATE IN OUT DATE,
OUTNUMBER OUT NUMBER,
OUTVARCHAR OUT VARCHAR2,
OUTDATE OUT DATE
) AS
BEGIN
...
END;
/
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class SCOTTProcedureClient : System.ServiceModel.ClientBase<SCOTTProcedure>, SCOTTProcedure {
public System.Nullable<decimal> SAMPLE_PROCEDURE
(
System.Nullable<decimal> INNUMBER,
string INVARCHAR,
System.Nullable\<System.DateTime\> INDATE,
ref System.Nullable<decimal> INOUTNUMBER,
ref string INOUTVARCHAR,
ref System.Nullable\<System.DateTime\> INOUTDATE,
out string OUTVARCHAR,
out System.Nullable\<System.DateTime\> OUTDATE
);
}
Unterstützung für überladene Prozeduren, Funktionen und Pakete
Der Oracle Database-Adapter unterstützt überladene Prozeduren, Funktionen und Pakete, indem eine eindeutige Zeichenfolge an die Knoten-ID und den Namespace angefügt wird, der für jedes überladene Artefakt angezeigt wird. Diese Zeichenfolge ist "overload1" für die erste Überladung, "overload2" für die nächste Überladung usw.
Im WCF-Dienstmodell wird jede überladene Prozedur oder Funktion durch einen eindeutigen WCF-Client dargestellt. Dies unterscheidet sich von dem nicht überladenen Fall, in dem alle Funktionen in einem SCHEMA, alle Prozeduren in einem SCHEMA oder alle Prozeduren und Funktionen in einem PACKAGE vom gleichen WCF-Client aufgerufen werden. Die folgende Tabelle zeigt den WCF-Clientnamen und die Methode, die für überladene Prozeduren, Funktionen und Pakete generiert wurden.
Oracle-Artefakt | WCF-Clientname | Beispiel |
---|---|---|
Überladenes Paket (Prozedur) | [SCHEMA] Package[PACKAGE_NAME][PROC_NAME] ][OVERLOAD_ID]Client. [PROC_NAME] | SCOTTPackageMYPACKAGEMYPROCoverload1Client.MYPROC |
Überladenes Paket (Funktion) | [SCHEMA] Package[PACKAGE_NAME][FUNC_NAME] ][OVERLOAD_ID]Client. [FUNC_NAME] | SCOTTPackageMYPACKAGEMYFUNCoverload1Client.MYFUNC |
[SCHEMA] = Sammlung von Oracle-Artefakten; z. B. SCOTT.
[PROC_NAME] = Der Name einer Oracle-Prozedur; Zum Beispiel; MYPROC.
[FUNC_NAME] = Der Name einer Oracle-Funktion; z. B. MYFUNC.
[PACKAGE_NAME] = Der Name eines Oracle-Pakets.
[OVERLOAD_ID] = Die eindeutige Zeichenfolge, die das überladene Artefakt identifiziert; "overload1", "overload2" usw.
Die folgende Tabelle zeigt den Namespace, der für überladene Prozeduren, Funktionen und Pakete generiert wird.
Oracle-Artefakt | Namespace | Beispiel |
---|---|---|
Paket (Prozedur) | [BASE_NS]. [SCHEMA]. Paket. [PACKAGE_NAME]. [PROC_NAME] [OVERLOAD_ID] | microsoft.lobservices.oracledb._2007._03.SCOTT. Package.MYPACKAGE.MYPROC.overload1 |
Paket (Funktion) | [BASE_NS]. [SCHEMA]. Paket. [PACKAGE_NAME]. [FUNC_NAME]. [OVERLOAD_ID] | microsoft.lobservices.oracledb._2007._03.SCOTT. Package.MYPACKAGE.MYFUNC.overload1 |
Generischer Datensatzsatz (schwach typisiert) | [BASE_NS] | microsoft.lobservices.oracledb._2007._03 |
[BASE_NS] = Der Basisadapternamespace; microsoft.lobservices.oracledb._2007._03.
[SCHEMA] = Sammlung von Oracle-Artefakten; z. B. SCOTT.
[PROC_NAME] = Der Name einer Oracle-Prozedur; Zum Beispiel; MYPROC.
[FUNC_NAME] = Der Name einer Oracle-Funktion; z. B. MYFUNC.
[PACKAGE_NAME] = Der Name eines Oracle-Pakets.
[OVERLOAD_ID] = Die eindeutige Zeichenfolge, die das überladene Artefakt identifiziert; "overload1", "overload2" usw. Der numerische Wert in der Zeichenfolge ist die Überladungs-ID für das Artefakt, das von der Oracle-Datenbank verwaltet wird.
Das folgende Beispiel zeigt die WCF-Clients und die Methodensignaturen, die für die überladene GET_ACCOUNT-Prozedur im ACCOUNT_PKG-Paket generiert wurden. (Die Oracle-Deklarationen sind enthalten.) Dieses Beispiel zeigt, wie für jede Überladung ein eindeutiger WCF-Client generiert wird und wie die für jeden Client generierte Methode einen Datensatzsatz in einem eindeutigen Namespace zurückgibt.
/* Procedure that takes account ID and returns record for existing account in the ACCOUNT table */
PROCEDURE get_account(aid IN account.acctid%TYPE, acct OUT account%ROWTYPE) ;
/* Procedure that takes account name and returns record for existing account in the ACCOUNT table */
PROCEDURE get_account(aname IN account.name%TYPE, acct OUT account%ROWTYPE) ;
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload1Client : System.ServiceModel.ClientBase<SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload1>, SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload1 {
public microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNT.overload1.ACCTRECORD GET_ACCOUNT(System.Nullable<decimal> AID);
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload2Client : System.ServiceModel.ClientBase<SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload2>, SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload2 {
public microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNT.overload2.ACCTRECORD GET_ACCOUNT(string ANAME);
}
Aufrufen von Funktionen und Prozeduren
Führen Sie die folgenden Schritte aus, um eine Funktion oder eine Prozedur mithilfe eines WCF-Clients aufzurufen.
Generieren Sie eine WCF-Clientklasse für die Zielfunktion, Prozedur oder das Zielpaket. Diese Klasse sollte Methoden für die Vorgänge enthalten, die Sie für das Zielartefakt aufrufen.
Hinweis
Im Visual Studio-Plug-In Adapterdienstverweis hinzufügen werden überladene Funktionen und Prozeduren im Feld Verfügbare Kategorien und Vorgänge als [NAME].1, [NAME].2, [NAME].3 usw. angezeigt, wobei [NAME] der Name des überladenen Artefakts und der numerische Wert die Überladungs-ID in der Oracle-Datenbank ist.
Erstellen Sie eine instance der WCF-Clientklasse, und rufen Sie deren Methoden auf, um die Funktion oder Prozedur aufzurufen.
Ausführlichere Informationen zum Erstellen einer WCF-Clientklasse und zum Aufrufen von Vorgängen für den Oracle Database-Adapter finden Sie unter Übersicht über das WCF-Dienstmodell mit dem Oracle-Datenbankadapter.
Der Oracle Database-Adapter führt jeden Vorgang innerhalb einer Transaktion für die Oracle-Datenbank aus.
Wichtig
Die Klassen, die REF CURSOR- und RECORD-Typparameter oder Rückgabewerte in Funktionen oder Prozeduren (und Paketen) darstellen, werden in einem eindeutigen Namespace für jede Funktion oder Prozedur deklariert. Dies bedeutet beispielsweise, dass ein PACKAGE REF CURSOR-Typ, der in zwei verschiedenen Funktionen als Rückgabewert verwendet wird, in einem eindeutigen Namespace für jede WCF-Clientmethode deklariert wird. Sie müssen entweder separate Variablen deklarieren, um diese unterschiedlichen Rückgabewerte zu enthalten, oder die Variable ordnungsgemäß umwandeln, wenn Sie eine der WCF-Clientmethoden aufrufen.
Im folgenden Beispiel wird das Aufrufen der überladenen Prozedur /SCOTT/Package/ACCOUNT_PKG/GET_ACCOUNT veranschaulicht, um Kontodatensätze aus der Tabelle /SCOTT/ACCOUNT abzurufen. Zunächst wird ein neuer Datensatz erstellt, indem die Prozedur /SCOTT/Package/ACCOUNT_PKG/CREATE_ACCOUNT aufgerufen wird. Anschließend wird der neue Datensatz zweimal zurückgelesen, indem verschiedene Überladungen von GET_ACCOUNT aufgerufen werden. In diesem Beispiel werden drei WCF-Clients verwendet, einer für die CREATE_ACCOUNT-Prozedur und jeweils einer für die GET_ACCOUNT-Überladungen. Aliase werden verwendet, um zwischen Namespaces zu unterscheiden, die für den Rückgabewert von GET_ACCOUNT verwendet werden. Ein vollständiges Beispiel finden Sie in den SDK-Beispielen. Weitere Informationen zu den SDK-Beispielen finden Sie unter Beispiele im SDK.
using System;
using System.Collections.Generic;
using System.Text;
// 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;
// Alias client namespaces to shorten declarations of "shared" types
using CREATE_ACCOUNTns = microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.CREATE_ACCOUNT;
using GET_ACCOUNT_BY_IDns = microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNT.overload1;
using GET_ACCOUNT_BY_NAMEns = microsoft.lobservices.oracledb._2007._03.SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNT.overload2;
// This sample demonstrates calling overloaded packaged procedures on Oracle
// First a new account is created by calling CREATE_ACCOUNT which takes two record parameters
// Then the information for the new account is returned by calling an overloaded procedure GET_ACCOUNT
// The first overload returns the account information by account ID
// The second overload returns the account information by account name
// Notice that different clients (and namespaces) are created for overloaded procedures and functions
namespace OracleOverloadsSM
{
class Program
{
static void Main(string[] args)
{
decimal acctId;
string newAccountName = "Paula Bento";
Console.WriteLine("Creating clients");
// Create Client for CREATE_ACCOUNT Function
SCOTTPackageACCOUNT_PKGClient createAccountClient =
new SCOTTPackageACCOUNT_PKGClient("OracleDBBinding_SCOTT.Package.ACCOUNT_PKG");
// NOTE: user name and password are case-sensitive
createAccountClient.ClientCredentials.UserName.UserName = "SCOTT";
createAccountClient.ClientCredentials.UserName.Password = "TIGER";
// Create Client for GET_ACCOUNT Overload 1 -- takes ACCOUNT ID parameter
SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload1Client getAccountByIdClient =
new SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload1Client("OracleDBBinding_SCOTT.Package.ACCOUNT_PKG.GET_ACCOUNT.overload1");
// NOTE: user name and password are case-sensitive
getAccountByIdClient.ClientCredentials.UserName.UserName = "SCOTT";
getAccountByIdClient.ClientCredentials.UserName.Password = "TIGER";
// Create Client for GET_ACCOUNT Overload 2 -- takes ACCOUNT NAME parameter
// NOTE: this client can be created from configuration; detail provided here
// for demonstration
OracleDBBinding overload2Binding = new OracleDBBinding();
EndpointAddress overload2EndpointAddress = new EndpointAddress("oracleDB://ADAPTER");
SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload2Client getAccountByNameClient =
new SCOTTPackageACCOUNT_PKGGET_ACCOUNToverload2Client(overload2Binding, overload2EndpointAddress);
// NOTE: user name and password are case-sensitive
getAccountByNameClient.ClientCredentials.UserName.UserName = "SCOTT";
getAccountByNameClient.ClientCredentials.UserName.Password = "TIGER";
try
{
Console.WriteLine("Opening clients -- please wait");
// Open clients
createAccountClient.Open();
getAccountByIdClient.Open();
getAccountByNameClient.Open();
Console.WriteLine("Creating new account");
// Create an account record
// NOTE: ACCTRECORD is defined in all three namespaces so specify the definition
// that corresponds to the client.
CREATE_ACCOUNTns.ACCTRECORD acctRec = new CREATE_ACCOUNTns.ACCTRECORD();
// Set any value for ACCTID -- new account ID is returned by CREATE_ACCOUNT
acctRec.ACCTID = 0;
acctRec.NAME = newAccountName;
acctRec.BALANCE = 10537;
// Create address record
CREATE_ACCOUNTns.ACCOUNT_PKGADDRESS_REC_TYPERECORD addrRec = new CREATE_ACCOUNTns.ACCOUNT_PKGADDRESS_REC_TYPERECORD();
addrRec.STREET = "456 Valley Rd";
addrRec.CITY = "New York";
addrRec.STATE = "NY";
// Create account
acctId = (decimal)createAccountClient.CREATE_ACCOUNT(acctRec, addrRec);
Console.WriteLine("New Account Created: AccountId = {0}, Name = {1}, Balance = {2:C}",
acctId, acctRec.NAME, acctRec.BALANCE);
/* Get new account by Id */
GET_ACCOUNT_BY_IDns.ACCTRECORD acctById = getAccountByIdClient.GET_ACCOUNT(acctId);
Console.WriteLine("Account Returned by Id: AccountId={0}, Name={1}, Balance={2:C}",
acctById.ACCTID, acctById.NAME, acctById.BALANCE);
/* Get new account by Name */
GET_ACCOUNT_BY_NAMEns.ACCTRECORD acctByName = getAccountByNameClient.GET_ACCOUNT(newAccountName);
Console.WriteLine("Account Returned by Name: AccountId={0}, Name={1}, Balance={2:C}",
acctByName.ACCTID, acctByName.NAME, acctByName.BALANCE);
Console.WriteLine("Hit <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 all the clients
createAccountClient.Close();
getAccountByIdClient.Close();
getAccountByNameClient.Close();
}
}
}
}
Weitere Informationen
Entwickeln von Oracle-Datenbankanwendungen mithilfe des WCF-Dienstmodells