不允许使用带有WHERE子句的SqlDependency查询。如何修改它才有效?

时间:2010-03-03 18:06:59

标签: c# sql-server-2005 .net-3.5 sqldependency

我使用以下查询设置了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事件持续触发,其类型为无效语句来源。我进一步研究后发现,当您的查询违反与索引视图规则相同的规则时会发生什么,因为这是此通知机制所基于的。

检查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事件仅在适当时触发,并且具有正确的类型集。

那么,我怎样才能返回自上次执行语句以来修改日期的记录?

3 个答案:

答案 0 :(得分:5)

ModifyDT是什么类型的?

QN的ADO.Net参考不完整,完整列表位于Creating a Query for Notification的SQL参考中。后者还列出了以下内容:

  

声明不得进行比较   或基于double / real的表达式   数据类型。

另一个问题可能是在查询中发生从字符串到日期时间的转换,这可能被认为是非确定性的(这是ADO.Net和SQL规范列出的标准)。请尝试使用类型化参数:WHERE ModifyDT > @lastDateTime并传入DateTime类型的参数。

答案 1 :(得分:2)

你显然有一些东西可以在

中生成日期
  

LastExecutionDateTime

因此,不要在SQL上创建SqlDependency,而是使用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);

答案 2 :(得分:0)

如果您还没有想到这一点,那么问题的3部分表名就像这样试试。

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