【问题标题】:Change notification Issue with oracle 12coracle 12c 的更改通知问题
【发布时间】:2014-10-01 16:29:25
【问题描述】:
OracleCommand cmd =
new OracleCommand("select * from Test WHERE TestFLAG = 1 or TestFLAGis not null", con);

当桌子发生变化时,无论条件如何,我的 .net 项目仍然会收到通知。

对于第二个问题,在我第一次收到任何通知后,此后桌子上的任何更改都不会得到通知。为什么?

我的问题有什么解决办法吗?

public class MyNotificationSample
{
    static string constr = "your db INFO";
    public static bool IsNotified = false;
    static OracleDependency dep = null;

    public static void Main(string[] args)
    {
        //To Run this sample, make sure that the change notification privilege
        //is granted to scott.
        OracleConnection con = null;


        try
        {
            con = new OracleConnection(constr);
            OracleCommand cmd = new OracleCommand("select * from Test WHERE TestFLAG = 1 or TestFLAGis not null", con);
            con.Open();

            // Set the port number for the listener to listen for the notification
            // request
            OracleDependency.Port = 1005;

            // Create an OracleDependency instance and bind it to an OracleCommand
            // instance.
            // When an OracleDependency instance is bound to an OracleCommand
            // instance, an OracleNotificationRequest is created and is set in the
            // OracleCommand's Notification property. This indicates subsequent 
            // execution of command will register the notification.
            // By default, the notification request is using the Database Change
            // Notification.
            dep = new OracleDependency(cmd);

            // Add the event handler to handle the notification. The 
            // OnMyNotification method will be invoked when a notification message
            // is received from the database
            dep.OnChange += OnMyNotificaton;

            // The notification registration is created and the query result sets 
            // associated with the command can be invalidated when there is a 
            // change.  When the first notification registration occurs, the 
            // notification listener is started and the listener port number 
            // will be 1005.
            cmd.ExecuteNonQuery();

        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }

        con.Close();

        Console.Write("Press Any Key to Quit");
        Console.ReadLine();
        // Loop while waiting for notification
    }

    public static void OnMyNotificaton(object src,
      OracleNotificationEventArgs arg)
    {
        if (dep.HasChanges)
        {
            Console.WriteLine("Notification Received");
            DataTable changeDetails = arg.Details;
            Console.WriteLine("Data has changed in {0}",
              changeDetails.Rows[0]["ResourceName"]);
        }

    }

最新更新:使监听器永不过期。

new OracleDependency(cmd, false, 0 , true);

但是,我的查询仍然不起作用...

【问题讨论】:

  • 我认为您需要在此处提供有关您的实施的更多详细信息。您能发布一个简化但功能正常的示例吗?
  • @nineside 已更新。请看一下

标签: c# oracle oracle12c


【解决方案1】:

您的查询有这个WHERE 子句:TestFLAG = 1 or TestFLAGis not null
TestFLAGis not null 之间可能缺少空格。在这种情况下,表达式的第一部分是不必要的,如TestFLAG = 1,则它不为空。
也许问题在于,您的查询覆盖的范围比您预期的要多。

除此之外,Oracle 的数据库更改通知功能不保证您只会收到查询实际返回的行的通知。它保证您会收到这些行的通知,但您也可能会收到“误报”,因此实际上与您的查询匹配的行的通知。

这可能是来自Oracle Docs(强调我的)的一个很好的解释:

基于查询的注册有两种模式:保证模式和 尽力而为模式。在保证模式下,任何数据库更改通知 确保查询中包含的内容发生更改 结果集。但是,如果查询很复杂,则不能 在保证模式下注册。在这种情况下使用尽力而为模式。

尽力而为模式简化了基于查询注册的查询。不 通知因简化而丢失。然而 简化可能会导致误报,因为更简单的版本 当原始查询结果发生变化时,查询结果可能会发生变化 不是。对于哪些查询可以有一些限制 尽力而为模式基于查询的注册。在这种情况下,开发商 可以使用基于对象的注册,可以注册大多数查询 类型。基于对象的注册会在 查询对象改变,即使实际查询结果没有改变。这 也意味着基于对象的注册更容易出错 比基于查询的注册更积极。开发者应该知道 每个数据库更改的相对优势和劣势 通知选项并选择最适合他们的 要求。

关于第二个问题,正如@user1415516 所写,您需要将您的通知设置为在第一次通知后不取消注册,因此在执行命令之前添加cmd.Notification.IsNotifiedOnce = false;

【讨论】:

    【解决方案2】:

    将此添加到您的代码中

    cmd.Notification.IsNotifiedOnce = false;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-09
      • 1970-01-01
      • 2020-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多