oracle 12c的变更通知问题

本文关键字:通知 问题 12c oracle | 更新日期: 2023-09-27 18:16:59

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);

oracle 12c的变更通知问题

添加到您的代码

cmd.Notification。IsNotifiedOnce = false;

您的查询有WHERE子句:TestFLAG = 1 or TestFLAGis not null
TestFLAGis not null之间可能有空白。在这种情况下,表达式的第一部分是不必要的,当TestFLAG = 1,那么它不是空的。
也许问题是,你的查询涵盖的范围比你预期的要大得多。

除此之外,Oracle的数据库更改通知功能并不能保证你只会收到查询实际返回的行的通知。它保证,你会得到那些行的通知,但你也可以得到"误报",所以通知实际上匹配你的查询。

这可能是一个很好的解释从Oracle文档(强调我):

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

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

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