Зависимость C # срабатывает только тогда, когда в MS SQL вставлены новые строки с определенным значением столбца - PullRequest
6 голосов
/ 26 марта 2019

Я хочу получить событие "изменения", когда в MS SQL были вставлены новые строки с определенным значением столбца.

Ниже приведен код, который я сейчас использую, который работает довольно хорошо, за исключением того, что он вызываетсобытие, когда любое значение строки в столбце [Status] меняется на / OR с "NEW".

public void InitialiseDependencyWORK(Action onDependencyMethod)
{

    this.onDependencyMethod = onDependencyMethod;

    string sqlCommandText = "SELECT [Symbol] FROM [JJ].[Orders] WHERE [Status] = 'NEW'";

    using (SqlCommand command = new SqlCommand(sqlCommandText, conn))
    {

        Dependency = new SqlDependency(command);

        Dependency.OnChange += new OnChangeEventHandler(OnDependencyChange);

        using (SqlDataReader reader = command.ExecuteReader())
        {
            // Process the DataReader.
        }
    }

}

void OnDependencyChange(object sender,
   SqlNotificationEventArgs e)
{
    // Handles NEW rows
}

Меня интересует только когда новая строка вставляется с [Status] = "NEW", но это событиетакже запускается, когда нет новой вставки, НО [Статус] изменился с «НОВОГО» на что-либо еще.

Как я могу получить событие триггера, только если была новая вставка?

Я хотел бы получить событие триггера, когда строки новостей были вставлены, как строка 2 ниже:

OrderID, Status 
1,Done 
2,NEW 

Я не хочу, чтобы это инициировало, потому что строка 2 только что обновила свой статус - фактически нетновая строка для обработки:

OrderID, Status
1,Done
2,Done

Как этого добиться?

Ответы [ 3 ]

2 голосов
/ 03 апреля 2019

Общий вариант использования SqlDependency предназначен для обнаружения изменений в данных, которые не очень часто изменяются, которые вы хотели бы кэшировать, но также должны знать, если они действительно изменяются, чтобы вы могли обновить кэш без опросабаза данных.Ваш случай немного отличается тем, что вы на самом деле не хотите знать, когда изменяются результаты этого запроса ... вы хотите знать, когда определенный запрос содержит результаты для обработки.Причина, по которой вы получаете уведомление, когда код состояния меняется на «И» с «НОВОГО», заключается в том, что оба этих типа изменений изменят результаты запроса.Это сложение и вычитание целых строк на основе обоих видов изменений.

Если вы используете только коды состояния «NEW» и «DONE», и они гарантированно всегда инициируются как «NEW» и прогрессируют только впередна «ВЫПОЛНЕНО» (и никогда не возвращаться), тогда можно использовать этот запрос:

SELECT [OrderID] FROM [JJ].[Orders] WHERE [Status] <= 'NEW'

Таким образом, новый элемент, добавленный в статус «НОВЫЙ», изменит результаты запроса ... но когдаон перемещается в «ГОТОВО», он все равно будет возвращен в запросе OrderID и не должен вызывать событие изменения.Если у вас есть больше значений статуса, вы прогрессируете, хотя ... вы можете рассмотреть возможность использования целого числа в столбце статуса, чтобы указать прогресс.Например, 0 для нового, 1 в процессе, 2 выполнено ... и т. Д.

Звучит так, как будто вы пытаетесь создать какую-то очередь выполняемой работы, и есть другие способы сделать этовещи тоже.Существует отслеживание изменений SQL Server и отслеживание изменений данных, триггеры, очереди Service Broker и множество других технологий организации очередей.Вы можете проверить их, а также варианты вашей архитектуры.

2 голосов
/ 26 марта 2019

Могу я спросить, почему вы изобретаете триггеры SQL в c # для контекста? https://docs.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql?view=sql-server-2017

Самое простое решение - зафиксировать это в самой таблице, а не с помощью запроса, который даст ложные срабатывания.

В качестве альтернативы, если вы выполняете весь свой код через уровень хранилища, тогда вы сможете отличить INSERT от UPDATE и выбрать его там же.

0 голосов
/ 05 апреля 2019

Я думаю, что событие SqlDependency запускается всякий раз, когда в таблице есть какая-либо вставка / обновление / удаление.

Нет способа остановить его.

вы можете перехватить соответствующий тип уведомления в событии иВы работаете.

void OnDependencyChange(object sender,
   SqlNotificationEventArgs e)
{
    if (e.Info == SqlNotificationInfo.Insert)
}

Другой способ сделать это, который я не пробовал,

Создать другую таблицу OrdersCopy, которая является копией [JJ].[Orders]

Создать триггер вставки в таблице заказов.

Всякий раз, когда в таблице заказов есть вставка, триггер срабатывает.Вставьте новую запись в OrdersCopy

Здесь сделайте следующее изменение, измените имя таблицы на OrderCopy

string sqlCommandText = "SELECT [Symbol] FROM [JJ].[OrdersCopy] WHERE [Status] = 'NEW'";

Для встряхивания эксперимента вы можете попробовать это один раз.

OnDependencyChange Событие сработает только в случае вставки.

...