Запрос SqlDependency с предложением WHERE не разрешен. Как я могу изменить его, чтобы он действовал? - PullRequest
3 голосов
/ 03 марта 2010

У меня есть SqlDependency, настроенный с помощью следующего запроса:

string sql = "SELECT dbo.Case.CMRID, dbo.Case.SolutionID, dbo.Case.CreateDT, dbo.Case.ModifyDT "
+ "FROM dbo.Case "
+ "WHERE dbo.Case.ModifyDT > @LastExecutionDateTime";

При выполнении этого запроса событие OnChanged будет запускаться непрерывно с типом Invalid и Source Заявление .Что после дальнейших исследований я обнаружил, что происходит, когда ваш запрос нарушает правила, которые совпадают с правилами для индексированных представлений, поскольку именно на этом основан механизм уведомлений.

Проверка Особые соображения при использовании запросаУведомления (ADO.NET) Я не вижу каких-либо правил, нарушающих это утверждение.

Изменение оператора на

string sql = "SELECT dbo.Case.CMRID, dbo.Case.SolutionID, dbo.Case.CreateDT, dbo.Case.ModifyDT "
+ "FROM dbo.Case";

Работает правильно.Событие OnChanged срабатывает только при необходимости и имеет правильный установленный тип.

Итак, как я могу вернуть записи только с датой изменения с момента моего последнего выполнения оператора?

Ответы [ 3 ]

5 голосов
/ 03 марта 2010

Какой тип ModifyDT?

Ссылка ADO.Net для QN неполная, полный список в справочнике SQL по адресу Создание запроса на уведомление . Последний также перечисляет следующее:

Заявление не должно иметь сравнения или выражение, основанное на двойном / реальном типы данных.

Другая проблема может заключаться в приведении строки к дате и времени, которое происходит в вашем запросе, что может считаться недетерминированным (что является критерием, указанным в спецификации ADO.Net и SQL). Попробуйте вместо этого ввести типизированный параметр: WHERE ModifyDT > @lastDateTime и передать параметр типа DateTime.

2 голосов
/ 05 августа 2011

У вас, очевидно, есть что-то, что генерирует дату уже в

LastExecutionDateTime

Таким образом, вместо создания SqlDependency в SQL, используйте объект SqlCommand

string sql = "SELECT CMRID, SolutionID, CreateDT, ModifyDT " + "FROM dbo.Case " + "WHERE ModifyDT > @lastExecutionDateTime"; 
//notice the parameter @lastExecutionDateTime, you cant use dates as a string, you also cant use something like CONVERT(datetime, '20040508'). You need a real date time object, hence the parameter

//You also only need to use the two part table ref (dbo.x) in the FROM clause, you dont need it on every field
//and while you didnt do it here, if anyone is interested a two part table ref in the form of dbo.[Case] would fail because the brackets will kill your dependency subscription

SqlCommand dependencyCommand= new SqlCommand(sql);
dependencyCommand.Parameters.Add(new SqlParameter("lastExecutionDateTime", SqlDbType.DateTime) {
        Value = LastExecutionDateTime 
    });

тогда просто создайте свою зависимость по команде

//Create a dependency object and associate it with the SqlCommand.
SqlDependency dependency = new SqlDependency();
dependency.AddCommandDependency(dependencyCommand);
//Subscribe to the SqlDependency event.
dependency.OnChange += new OnChangeEventHandler(OnDependencyChange);

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

//get the most recent data
DataTable currentDependencyData = new DataTable();
SqlDataAdapter dataAdapter = new SqlDataAdapter(dependencyCommand);
dataAdapter.Fill(currentDependencyData);
0 голосов
/ 17 июня 2014

Если вы еще не поняли это, имя таблицы из 3 частей, которая является проблемой, попробуйте это так.

"SELECT [CMRID], 
       [SolutionID], 
       [CreateDT], 
       [ModifyDT] 
FROM [dbo].[Case] 
WHERE [ModifyDT] > " + LastExecutionDateTime;
...