有人知道如何使用PL / SSQL和ODP.NET从C#实现Oracle Advance Queue? 我在C#或VB.NET中找不到具有具体示例的单个示例或资源。 理想情况下,我想了解一些关于如何使用简单类型(XMl / string)对消息进行入队和出列的示例。
答案 0 :(得分:17)
我无法帮助您掌握最佳实践,但我可以帮助您使用UDT队列。在处理队列之前,需要从数据库生成自定义类型到C#项目中。假设您安装了Visual Studio和ODP.NET,您只需要通过Server Explorer连接到数据库,找到您的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);
_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;
}
这是一个类似的出队过程:
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;
}
这是一个“简单”的例子。我从Ed Zehoo的Pro ODP.NET for Oracle Database 11g中删除了大部分内容。这是一本很好的书,我强烈建议它帮助你更好地理解OPD.NET所有东西的来龙去脉。您可以在此处购买电子书:http://apress.com/book/view/9781430228202。如果您输入优惠券代码MACWORLDOC,您可以以21.00美元的价格购买电子书。该优惠仅适用于受密码保护的PDF格式的电子书。我希望这有帮助!
答案 1 :(得分:3)
我不知道这个问题的确切答案,但这就是我们所做的:
答案 2 :(得分:3)
我有一个要求,我必须将UDT消息排队/出列到队列。这篇文章真有帮助。几乎所有东西都缺少了“Oracle Custom Type”的创建。我认为值得在这里添加代码,以便解决方案完整。
到Oracle的EnQueue / DeQueue:
必须创建角色为“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();
}
}
答案 3 :(得分:2)
这是我从Oracle发现的一个很好的例子。
http://www.oracle.com/technetwork/issue-archive/2009/09-nov/o69net-099734.html
代码:http://www.oracle.com/technetwork/issue-archive/2009/09-nov/o69odt-131369.zip
答案 4 :(得分:0)
AQ通过DBMS_AQ [adm]有plsql接口。您只需要从您的环境和常见的AQ示例和设置中运行这些包。当您从c#调用这些包时,我认为没有什么特别的。