2010-03-03 1 views
3

У меня есть SqlDependency настроить с помощью следующего запроса:Запрос SqlDependency с предложением WHERE не разрешен. Как я могу изменить его, чтобы он был действительным?

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 и источником Заявления. Что после дальнейших исследований, которые я нашел, это то, что происходит, когда ваш запрос нарушает правила, которые являются такими же, как правила для индексированных представлений, поскольку на этом основан этот механизм уведомления.

Проверка Special Considerations Using Query Notifications (ADO.NET) Я не вижу никаких правил, которые я нарушаю с этим утверждением.

Изменение заявление

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

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

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

ответ

5

Какой тип ModifyDT?

Ссылка ADO.Net для QN неполна, полный список находится в ссылке SQL на Creating a Query for Notification. Последнее также перечисляет следующее:

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

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

+0

ModifyDT - это DateTime на сервере. LastExecutionDateTime - это структура DateTime, которая, конечно, вызывает ToString(), вызываемую им неявно. –

2

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

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

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

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