本節包含如何從 WCF 服務模型叫用 ReadLOB 和 UpdateLOB 作業的相關信息。 ReadLOB 和 UpdateLOB 作業會針對包含 LOB 欄位的資料表和檢視表呈現,即用來儲存 Oracle 大型物件(LOB)資料的欄位。 如需 Microsoft BizTalk Adapter for Oracle Database 所支援的 Oracle LOB 資料類型以及 ReadLOB 和 UpdateLOB 作業的概觀,請參閱 包含 LOB 資料的 Oracle 資料庫資料表和檢視上的作業。
這很重要
LOB 數據行可以包含大量數據,最多 4 GB(GB)。 使用 WCF 用戶端操作 LOB 欄位的一項重大限制是,WCF 服務模型只支援在 ReadLOB 作業中進行數據串流,而不支援在 UpdateLOB 作業中。 這是因為 WCF 需要串流才能從服務模型運作,因此要串流的參數必須是其方向的唯一參數。 除了 LOB 數據之外,UpdateLOB 作業還有另外兩個 IN 參數(資料行名稱和數據列篩選條件):基於這個理由,WCF 服務模型中不支援串流。 因此,如果您要以大量數據更新 LOB 資料行,您可能想要使用 WCF 通道模型。 如需如何使用 WCF 通道模型使用 UpdateLOB 作業串流 LOB 數據的詳細資訊,請參閱 使用 WCF 通道模型串流 Oracle LOB 數據類型。
關於本主題中使用的範例
本主題中的範例會使用 /SCOTT/CUSTOMER 數據表。 此資料表包含名為 PHOTO 的 BLOB 資料行。SDK 範例會提供產生此數據表的腳本。 如需 SDK 範例的詳細資訊,請參閱 SDK 中的範例。
WCF 用戶端類別
下列範例顯示針對 /SCOTT/CUSTOMER 數據表上 ReadLOB 和 UpdateLOB 作業所產生的 WCF 用戶端類別的方法簽章。
public partial class SCOTTTableCUSTOMERClient : System.ServiceModel.ClientBase<SCOTTTableCUSTOMER>,
SCOTTTableCUSTOMER
{
public System.IO.Stream ReadLOB(string LOB_COLUMN, string FILTER);
public void UpdateLOB(string LOB_COLUMN, string FILTER, byte[] Stream);
}
備註
請注意 ,ReadLOB 會傳回數據流,但 UpdateLOB 不會在數據流上運作。
叫用 ReadLOB 和 UpdateLOB 作業
ReadLOB 和 UpdateLOB 方法只能在單一資料庫數據列的單一 LOB 數據行上作。 您設定以下參數來識別目標欄/列。
| 參數 | 定義 |
|---|---|
| LOB_COLUMN | FILTER 參數所識別數據列內的目標數據行名稱;例如,“PHOTO”。 |
| 過濾器 | 指定目標數據列之 SQL SELECT 語句 WHERE 子句的內容;例如,“NAME='Kim Ralls'”。 篩選條件必須指定一個數據列,而且只能指定一個數據列。 如果篩選條件匹配多行資料: - ReadLOB 會傳回第一個相符數據列的LOB數據。 - UpdateLOB 會拋出例外狀況。 |
備註
ReadLOB 傳回的數據流不支援 Seek。 這表示不支援 Length 之類的屬性。
謹慎
UpdateLOB 作業必須在交易範圍內執行。 此外,在執行 UpdateLOB 作業之前,UseAmbientTransaction 系結屬性必須設定為 true。
下列程式代碼示範如何使用 WCF 用戶端,從檔案更新 /SCOTT/CUSTOMER 資料表中的 BLOB PHOTO 資料行,並將新的數據行數據讀回檔案。 您可以在 SDK 範例中找到完整的範例。 如需 SDK 範例的詳細資訊,請參閱 SDK 中的範例。
using System;
using System.Collections.Generic;
using System.Text;
using System.Transaction;
// Include for file streaming
using System.IO;
// 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 the WCF channel model
using System.ServiceModel.Channels;
// Include this namespace for the WCF LOB Adapter SDK and Oracle Database adapter exceptions
using Microsoft.ServiceModel.Channels.Common;
using CustomerTablens = microsoft.lobservices.oracledb._2007._03;
namespace OracleLobOpsSnippetSM
{
class Program
{
static void Main(string[] args)
{
try
{
OracleDBBinding binding = new OracleDBBinding();
binding.UseAmbientTransaction = true; //set this to true for UpdateLOB operation
EndpointAddress endpointAddress = new EndpointAddress("oracleDB://ADAPTER");
using (SCOTTTableCUSTOMERClient customerTableClient =
new SCOTTTableCUSTOMERClient(binding, endpointAddress))
{
customerTableClient.ClientCredentials.UserName.UserName = "SCOTT";
customerTableClient.ClientCredentials.UserName.Password = "TIGER";
// Open the client to read the LOB data back
customerTableClient.Open();
// Add a photo to the customer record
using (FileStream fs = new FileStream("SamplePhoto.jpg", FileMode.Open))
{
Console.WriteLine("Updating photo");
int count = 0;
byte[] photo = new byte[fs.Length];
while ((count += fs.Read(photo, count, (int) (((fs.Length-count)>4096)? 4096:fs.Length-count))) \< fs.Length) ;
// UpdateLOB operation must be performed within a transaction scope
using(TransactionScope tx = new TransactionScope())
{
customerTableClient.UpdateLOB("PHOTO", "NAME='Kim Ralls'", photo);
Console.WriteLine("Photo updated");
tx.Complete();
}
}
// Read the data back and store it to another file
using (FileStream fs = new FileStream("PhotoCopy.jpg", FileMode.Create))
{
Console.WriteLine("Reading photo data");
Stream photoStream = customerTableClient.ReadLOB("PHOTO", "NAME='Kim Ralls'");
Console.WriteLine("Photo data read -- writing to PhotoCopy.jpg");
int count;
int length = 0;
byte[] buffer = new byte[4096];
while ((count = photoStream.Read(buffer, 0, 4096)) > 0)
{
fs.Write(buffer, 0, count);
length+=count;
}
Console.WriteLine("{0} bytes written to PhotoCopy.jpg", length);
}
}
Console.WriteLine("Photo updated and read back -- Hit <RETURN> to end");
Console.ReadLine();
}
catch (Exception ex)
{
// handle exception
Console.WriteLine("Exception caught: " + ex.Message);
}
}
}
}