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

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

4

2 回答 2

1

将此添加到您的代码中

cmd.Notification.IsNotifiedOnce = false;

于 2015-10-30T16:28:48.153 回答
1

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

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

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

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

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

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

于 2018-06-22T18:45:27.853 回答