2009-08-12 5 views
7

PL/SSQLとODP.NETを使用してC#からOracle Advance Queueを実装する方法を知っている人は誰ですか? C#またはVB.NETで具体的な例を持つ単一のサンプルまたはリソースが見つかりません。 理想的には、単純な型(XMl/string)でメッセージをエンキューおよびデキューする方法に関するいくつかの例を挙げたいと思います。Oracle Advanced Queuing with .Net

答えて

14

私はベストプラクティスをお手伝いすることはできませんが、私はUDTキューについてお手伝いできます。キューを処理する前に、データベースからC#プロジェクトにカスタムタイプを生成する必要があります。 Visual StudioとODP.NETがインストールされていると仮定すると、サーバーエクスプローラでデータベースに接続し、UDTを探し、右クリックして "Generate Custom Class ..."を選択するだけです。これらのクラスはUDTに直接マップされ、デキューされた情報を格納します。

private void main(string[] args) 
{ 
    string _connstring = "Data Source=host/DB;User 
    Id=USER;Password=PASSWORD1;"; 

    OracleConnection _connObj = new OracleConnection(_connstring); 

    // Create a new queue object 
    OracleAQQueue _queueObj = new OracleAQQueue("UDT_NAME", _connObj); 

    // Set the payload type to your UDT 
    _queueObj.MessageType = OracleAQMessageType.Udt; 
    _queueObj.UdtTypeName = "UDT_NAME"; 

    _connObj.Open(); 

    OracleTransaction _txn = _connObj.BeginTransaction(); 

    // Dequeue the message. 
    _queueObj.DequeueOptions.Visibility = OracleAQVisibilityMode.OnCommit; 
    _queueObj.DequeueOptions.Wait = 10; 
    OracleAQMessage _deqMsg = _queueObj.Dequeue(); 

    UDT_CUSTOM_CLASS data = (UDT_CUSTOM_CLASS)_deqMsg.Payload; 

    // At this point, you have the data and can do whatever you need to do with it 

    _txn.Commit(); 
    _queueObj.Dispose(); 
    _connObj.Close(); 
    _connObj.Dispose(); 
    _connObj = null; 

} 

「シンプル」の例です:

private void main(string[] args) 
{ 
    string _connstring = "Data Source=host/DB;User 
    Id=USER;Password=PASSWORD1;"; 

     OracleConnection _connObj = new OracleConnection(_connstring); 

     // Create a new queue object 
     OracleAQQueue _queueObj = new OracleAQQueue("UDT_NAME", _connObj); 

     _connObj.Open(); 

     OracleTransaction _txn = _connObj.BeginTransaction(); 

     // Set the payload type to your UDT 
     _queueObj.MessageType = OracleAQMessageType.Udt; 
     _queueObj.UdtTypeName = "UDT_NAME"; 

     // Create a new message object 
     OracleAQMessage _msg = new OracleAQMessage(); 

     // Create an instance of JobClass and pass it in as the payload for the 
     // message 
     UDT_CUSTOM_CLASS _custClass = new UDT_CUSTOM_CLASS(); 
     // Load up all of the properties of custClass 
     custClass.CustString = "Custom String"; 
     custClass.CustInt = 5; 

     _msg.Payload = custClass; 

     // Enqueue the message 
     _queueObj.EnqueueOptions.Visibility = OracleAQVisibilityMode.OnCommit; 
     _queueObj.Enqueue(_msg); 

     _txn.Commit(); 
     _queueObj.Dispose(); 
     _connObj.Close(); 
     _connObj.Dispose(); 
     _connObj = null; 
} 

それは、デキューする同様のプロセスがあります:ここでは

は、あなたがメッセージをエンキューするために使用するコードの例です。 Ed ZehooがOracle Database 11g用のPro ODP.NETの大半を引き出しました。優れた本ですので、OPD.NETのすべての機能の詳細を理解するのに役立つことを強くお勧めします。あなたはeBookをここで購入することができます: http://apress.com/book/view/9781430228202。クーポンコードMACWORLDOCを入力すると、$ 21.00でeBookを入手できます。このオファーは、パスワードで保護されたPDF形式のeBookにのみ適しています。私はこれが助けて欲しい!

0

AQにはDBMS_AQ [adm]によるplsqlインタフェースがあります。あなたが必要とするのは、あなたの環境や一般的なAQの例と設定からそのパッケージを実行するだけです。私はこれらのパッケージをC#から呼び出すときに特別なことはないと思います。

+0

申し訳ありませんが、私はPL/SQLとストアドプロシージャを使用する必要があります。問題は、メッセージをデキューするときに、多くのオプションが利用可能であることです。接続のタイムアウトデキューストアprocのパラメータとしてもUDTが使用されています - 10Gの.NetからUDTを作成する方法はわかりません。私が探しているのは、C#コードとベストプラクティスの例です(例えば、db接続を閉じるか開いたままにしますか?) – Geo

+0

これに関する例はありますか?私もこれを探しています。 ;) – user171523

3

私は、この問題に対する正確な答えを知っているが、ここで私たちが何をしたかではありません。

  • まず(AQ上に構築されたESB)ESB上でリッスンする必要があるすべての.NETアプリケーションを使用する必要があります彼自身のローカルOracle DBとそこからメッセージをデキューします。メッセージはローカルキューに伝播されます。これは、メッセージを受信するためにDB接続を開いたままにすることに関連する潜在的なスケーラビリティの問題を解決します。
  • 次に、ストアドプロシージャを基本的にカプセル化する独自のAQライブラリを作成しました。 - オラクルがODAC 11.1.0.7.20(AQをサポートするODP.NETを使用)を最終的にリリースしたため、これはもう必要ありません。メッセージ・コントラクトを定義するために、DTOのソートとしてOracle型を使用します。
+0

2番目のオプションは、私がデキューしたものです。興味深いことに、彼らはODP.NETを介して.NETで適切なサポートを追加しました。 – RichardOD

1

私はキューに/デキューUDTメッセージをエンキューしなければならなかったの要件を持っていました。この投稿は本当に役に立ちました。それはほとんどすべてを持っていますが、 "Oracle Custom Type"の作成はありません。私はそのコードをここに追加する価値があると思ったので、解決策は完成しました。 Oracleでエンキュー/デキューする

:役割 "AQ_ADMINISTRATOR_ROLE" と

ユーザーを作成する必要があります。下の例では、「AQUSER」がその役割で作成されています。

PL Sql to EnQueue: 

DECLARE 
    queue_options  DBMS_AQ.ENQUEUE_OPTIONS_T; 
    message_properties DBMS_AQ.MESSAGE_PROPERTIES_T; 
    message_id   RAW(16); 
    my_message   AQUSER.USER_DEFINED_TYPE; 
BEGIN 
    my_message := AQUSER.USER_DEFINED_TYPE('XXX','YYY','ZZZ'); 
    DBMS_AQ.ENQUEUE(
     queue_name => 'AQUSER.QUEUE_NAME', 
     enqueue_options => queue_options, 
     message_properties => message_properties, 
     payload => my_message, 
     msgid => message_id); 
    COMMIT; 
END; 
/

PL SQL to DeQueue 

DECLARE 
    queue_options  DBMS_AQ.DEQUEUE_OPTIONS_T; 
    message_properties DBMS_AQ.MESSAGE_PROPERTIES_T; 
    message_id   RAW(2000); 
    my_message   AQUSER.USER_DEFINED_TYPE; 
BEGIN 
    DBMS_AQ.DEQUEUE(
     queue_name => 'AQUSER.QUEUE_NAME', 
     dequeue_options => queue_options, 
     message_properties => message_properties, 
     payload => my_message, 
     msgid => message_id); 
    COMMIT; 
END; 
/

------------------------------------------------------------------------------------------- 

To create a Oracle Custom Type, you can use the following code: 

    public class CustomMessageType : IOracleCustomType, INullable 
    { 

     [OracleObjectMappingAttribute("XXXXX")] 
     public string XXXXX { get; set; } 

     [OracleObjectMappingAttribute("YYYYY")] 
     public string YYYYY { get; set; } 

     [OracleObjectMappingAttribute("ZZZZZ")] 
     public string ZZZZZ { get; set; } 

     public void FromCustomObject(Oracle.DataAccess.Client.OracleConnection con, IntPtr pUdt) 
     { 
      if (!string.IsNullOrEmpty(XXXXX)) 
      { 
       OracleUdt.SetValue(con, pUdt, "XXXXX", XXXXX); 
      } 
      if (!string.IsNullOrEmpty(YYYYY)) 
      { 
       OracleUdt.SetValue(con, pUdt, "YYYYY", YYYYY); 
      } 
      if (!string.IsNullOrEmpty(ZZZZZ)) 
      { 
       OracleUdt.SetValue(con, pUdt, "ZZZZZ", ZZZZZ); 
      } 
     } 

     public void ToCustomObject(Oracle.DataAccess.Client.OracleConnection con, IntPtr pUdt) 
     { 
      XXXXX = (string)OracleUdt.GetValue(con, pUdt, "XXXXX"); 
      YYYYY = (string)OracleUdt.GetValue(con, pUdt, "YYYYY"); 
      ZZZZZ = (string)OracleUdt.GetValue(con, pUdt, "ZZZZZ"); 
     } 

     public bool IsNull { get; set; } 

    } 


    [OracleCustomTypeMappingAttribute("SCHEMA.CUSTOM_TYPE")] 
    public class QueueMessageTypeFactory : IOracleCustomTypeFactory 
    { 
     public IOracleCustomType CreateObject() 
     { 
      return new CustomMessageType(); 
     } 
    }