Проблема с уведомлением об изменении с oracle 12c

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

Но мой запрос все еще не работает...


person king jia    schedule 08.08.2014    source источник
comment
Я думаю, вам нужно предоставить здесь намного больше подробностей о вашей реализации. Можете ли вы опубликовать упрощенный, но работающий пример?   -  person ninesided    schedule 08.08.2014
comment
@девятисторонний обновлен. Пожалуйста, взгляните   -  person king jia    schedule 08.08.2014


Ответы (2)


добавьте это в свой код

cmd.Notification.IsNotifiedOnce = false;

person user1415516    schedule 30.10.2015

В вашем запросе есть предложение WHERE: TestFLAG = 1 or TestFLAGis not null.
Вероятно, между TestFLAG и is not null отсутствует пробел. В этом случае первая часть выражения не нужна, так как если TestFLAG = 1, то оно не равно null.
Возможно, проблема в том, что ваш запрос охватывает гораздо больше территории, чем вы предполагали.

Кроме того, функция уведомлений об изменении базы данных Oracle не гарантирует, что вы будете получать уведомления только о строках, фактически возвращенных запросом. Это гарантирует, что вы получите уведомления для этих строк, но вы также можете получить «ложные срабатывания», то есть уведомления для строк, которые на самом деле не соответствуют вашему запросу.

Это может быть хорошим объяснением из Документов Oracle (выделено мной):

Регистрация на основе запросов имеет два режима: гарантированный режим и режим максимального усилия. В гарантированном режиме любое уведомление об изменении базы данных гарантирует, что произошло изменение чего-либо, содержащегося в запрошенном наборе результатов. Однако если запрос сложный, то он не может быть зарегистрирован в гарантированном режиме. В таких случаях используется режим максимального усилия.

Режим максимальных усилий упрощает запрос для регистрации на основе запроса. Никакие уведомления не теряются из-за упрощения. Однако упрощение может привести к ложным срабатываниям, так как результат запроса более простой версии может измениться, в то время как исходный результат запроса не изменился. Все еще остаются некоторые ограничения на то, какие запросы могут иметь регистрацию на основе запросов в режиме максимальных усилий. . В таких случаях разработчики могут использовать регистрации на основе объектов, которые могут регистрировать большинство типов запросов. Регистрации на основе объектов генерируют уведомления при изменении объекта запроса, даже если фактический результат запроса не изменяется. Это также означает, что регистрации на основе объектов более подвержены ложным срабатываниям, чем регистрации на основе запросов. Разработчики должны знать относительные сильные и слабые стороны каждого варианта уведомления об изменении базы данных и выбирать тот, который лучше всего соответствует их требованиям.

По второму вопросу, как писал @user1415516, вам нужно настроить уведомление так, чтобы оно не отменялось после первого уведомления, поэтому добавьте cmd.Notification.IsNotifiedOnce = false; перед выполнением команды.

person Hilarion    schedule 22.06.2018