我使用以下查询设置了SqlDependency:
string sql = "SELECT dbo.Case.CMRID, dbo.Case.SolutionID, dbo.Case.CreateDT, dbo.Case.ModifyDT "
+ "FROM dbo.Case "
+ "WHERE dbo.Case.ModifyDT > @LastExecutionDateTime";
Run Code Online (Sandbox Code Playgroud)
执行此查询会导致OnChanged事件持续触发,其类型为Invalid和Source of Statement.我进一步研究后发现,当您的查询违反与索引视图规则相同的规则时会发生什么,因为这是此通知机制所基于的.
使用查询通知检查特殊注意事项(ADO.NET)我没有看到任何违反此语句的规则.
将语句修改为
string sql = "SELECT dbo.Case.CMRID, dbo.Case.SolutionID, dbo.Case.CreateDT, dbo.Case.ModifyDT "
+ "FROM dbo.Case";
Run Code Online (Sandbox Code Playgroud)
工作正常吗?OnChanged事件仅在适当时触发,并且具有正确的类型集.
那么,我怎样才能返回自上次执行语句以来具有修改日期的记录?
我有一个在MS SQL Server 2005上运行的数据库和一个ASP.NET 3.5 Web应用程序.
该数据库包含一个产品目录,我用它来将"页面"提供给在Web应用程序中运行的CMS.创建页面后,应用程序会缓存它们,因此我需要通知应用程序此更改,以便重新创建页面对象.
CMS使用它自己的缓存,因此不能使用SqlCacheDependency来执行此任务.
当我启动应用程序时,我确实让订阅者出现在结果中
select * from sys.dm_qn_subscriptions
Run Code Online (Sandbox Code Playgroud)
但是,只要我向表中添加一些数据,订阅者就会消失,并且OnChanged事件永远不会触发.
在我的启动代码中,我有以下内容
// Ensure the database is setup for notifications
SqlCacheDependencyAdmin.EnableNotifications(DataHelper.ConnectionString);
SqlCacheDependencyAdmin.EnableTableForNotifications(DataHelper.ConnectionString, "Category");
SqlCacheDependencyAdmin.EnableTableForNotifications(DataHelper.ConnectionString, "Product");
if (!SqlDependency.Start(DataHelper.ConnectionString, SqlDependencyQueueName))
throw new Exception("Something went wrong");
string queueOptions = string.Format("service = {0}", SqlDependencyQueueName);
using (var connection = new SqlConnection(DataHelper.ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(@"SELECT [CategoryID],[Name]
FROM [dbo].[Category]", connection))
{
// Create a dependency and associate it with the SqlCommand.
dependency = new SqlDependency(command, queueOptions, 0);
// Subscribe …Run Code Online (Sandbox Code Playgroud) 是否可以SqlDependency在不执行查询的情况下在Sql Server中运行C#?
我有一些表可以增长得相当大.跨表执行查询以判断行是否已更改可能需要很长时间.
我已经设法让SqlDependency工作,但只要我不使用IsolationLevel.ReadUncommited我认为是与SqlDependency无关的SQL事务.
当我IsolationLevel.ReadUncommitted在事务中使用时(下面有很多注释),SqlDependency订阅失败,并立即OnChange通知:
sqlNotificationEventArgs.Info = "Isolation";
sqlNotificationEventArgs.Source = "Statement";
sqlNotificationEventArgs.Type = "Subscribe";
Run Code Online (Sandbox Code Playgroud)
当我删除IsolationLevel时,一切都按预期工作(当然,隔离是不对的).
这是我的相关代码:
private static string connString = "the connection string";
[MTAThread]
private static void Main(string[] args)
while(true)
{
using (var context = new LinqDataContext(connString))
{
var conn = context.Connection;
conn.Open();
/***********************************************************************/
/* Remove `IsolationLevel.ReadUncommitted` and the SqlDependency works */
/***********************************************************************/
using (var trans = conn.BeginTransaction(IsolationLevel.ReadUncommitted))
{
// simplified query, the real query uses UPDATE OUTPUT INSERTED
const string sqlCommand = "SELECT [Columns] FROM …Run Code Online (Sandbox Code Playgroud)
我有一张小桌子(大约200行),它一直在变化(每秒几次).
我一直在寻找一种解决方案,我可以在每次更改时接收来自数据库的通知,而不是轮询它(假设每秒5-10次).
此外,我想每次只接收更改的行而不是获取整个表 - 我发现使用SqlDependency类实现这一点相当困难.
要考虑的事情:
有没有办法使用SqlDependency做到这一点?
这种情况下最佳做法是什么?
顺便说一句:我正在使用SQL Server 2012
提前致谢
我是 SQL Server 查询通知的新手,我需要一些时间来理解它。
我的目标是创建一个 Windows 服务应用程序,当对 SQL Server 表进行更改时,该应用程序会收到通知。我遵循了本指南,这对我入门很有帮助。
但是我无法得到预期的结果。OnStart()我的 Windows 服务应用程序中的方法如下所示:
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("Service Started");
serviceRun = false;
SqlClientPermission perm = new SqlClientPermission(System.Security.Permissions.PermissionState.Unrestricted);
try
{
perm.Demand();
eventLog1.WriteEntry("permission granted");
}
catch (System.Exception)
{
eventLog1.WriteEntry("permission denied");
}
try
{
connstr = "Data Source=THSSERVER-LOCAL;Initial Catalog=ET;User ID=mujtaba;Password=ths123";
connection = new SqlConnection(connstr);
SqlCommand command = new SqlCommand("select * from dbo.Customer_FileUploads", connection);
// Create a dependency and associate it with the SqlCommand.
SqlDependency dependency = new …Run Code Online (Sandbox Code Playgroud) 我有一个成功使用SQL Server 2008 Standard Edition的SqlDependency的应用程序.但是,如果我将连接字符串切换到SQL Server 2008 express(启用Broker),它将停止工作.
我不确定它是否特定于SQL Server Express,但我应该遵循哪些步骤来找出问题的原因?
更新.通过"停止工作"我的意思是SqlDependency不会引发通知
我正在与SQLDependency班级一起探索查询通知。构建一个简单的工作示例很容易,但我觉得我错过了一些东西。一旦我跨过一个简单的单表/单依赖项示例,我就想知道 如何找出哪个依赖项触发了我的回调?
我在解释时遇到了一些麻烦,所以我在下面提供了一个简单的示例。当AChange()被调用时,我无法查看依赖项内的 sql,并且我没有对关联缓存对象的引用。
那么男孩该做什么呢?
Id属性和并行跟踪结构我只是错过了什么吗?这是结构上的缺陷吗SQLDependency?我已经看过 20 篇关于这个主题的不同文章,它们似乎都有相同的漏洞。建议?
代码示例
public class DependencyCache{
public static string cacheName = "Client1";
public static MemoryCache memCache = new MemoryCache(cacheName);
public DependencyCache() {
SqlDependency.Start(connString);
}
private static string GetSQL() {
return "select someString FROM dbo.TestTable";
}
public void DoTest() {
if (memCache["TEST_KEY"] != null ) {
Debug.WriteLine("resources found in cache");
return;
}
Cache_GetData();
}
private void Cache_GetData() { …Run Code Online (Sandbox Code Playgroud) sql-server ado.net sqldependency sql-server-2008-r2 query-notifications
我在控制台项目上使用它。
.NET框架:4.5
在我的测试代码中,onChange尽管数据库中没有数据更改,但 SQLDependency 始终会触发。
class Program
{
private static string _connStr;
static void Main(string[] args)
{
_connStr = "data source=xxx.xxx.xx.xx;User Id=xxx;Password=xxx; Initial Catalog=xxx";
SqlDependency.Start(_connStr);
UpdateGrid();
Console.Read();
}
private static void UpdateGrid()
{
using (SqlConnection connection = new SqlConnection(_connStr))
{
using (SqlCommand command = new SqlCommand("select msgdtl,msgid From NotifyMsg", connection))
{
command.CommandType = CommandType.Text;
connection.Open();
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
SqlDataReader sdr = command.ExecuteReader();
Console.WriteLine();
while (sdr.Read())
{
Console.WriteLine("msgdtl:{0}\t (msgid:{1})", sdr["msgdtl"].ToString(), sdr["msgid"].ToString());
}
sdr.Close(); …Run Code Online (Sandbox Code Playgroud) 我正在尝试SqlDependancy在SignalR项目中使用,但我似乎无法让OnChanged事件多次触发.它最初在订阅事件上触发,但在更改底层数据库后它永远不会再触发.我省略了SignalR和控制器代码,因为问题似乎在于存储库类.SqlDependancy.Start()在我Global.asax班上宣布.
从SQL服务器观察,我可以看到在我的应用程序启动时创建通知队列,并在关闭时终止.
public IEnumerable<Visitor> NotifyAllClients()
{
List<Visitor> visitors = new List<Visitor>();
using (var connection = new SqlConnection(new VisitorLogEntities().Database.Connection.ConnectionString))
{
using (var command = new SqlCommand(@"SELECT * FROM dbo.Visitors", connection))
//using (var command = new SqlCommand(@"SELECT [Id],[AgreeToTerms],[Base64Image],[CheckInDate],[CheckOutTime],[Company],[CountryOfOrigin],[email],[FirstName],[LastName],[IsInBuilding],[MeetingSubject],[MeetingTime],[PatriotHost],[phone],[title] FROM dbo.Visitors", connection))
{
var dependency = new SqlDependency(command);
dependency.OnChange += Database_OnChange;
if (connection.State == System.Data.ConnectionState.Closed)
connection.Open();
var reader = command.ExecuteReader();
while (reader.Read())
{
////compile visitor objects
////visitors.add(new Visitor());
}
}
return visitors.OrderByDescending(x => x.CheckInDate);
} …Run Code Online (Sandbox Code Playgroud) 我有一个桌面应用程序,应该在任何表更改时收到通知。因此,我只找到了两个非常适合我的情况的解决方案:SqlDependency和SQLCLR。(我想知道 .NET 堆栈中是否有更好的)我已经构建了两个结构并使它们工作。我只能比较从 SQL Server 到客户端的 s̲i̲n̲gl̲e̲ 响应的持续时间。
持续时间:从 100 毫秒到 4 秒
持续时间:从 10ms 到 150ms
我希望这个结构能够处理高速率通知*,我已经阅读了一些 SO 和博客文章(例如:here),并且我的同事也警告说,在大量请求时 SqlDependency 可能会出错。在这里,MS 提供了一些我没有得到的东西,这可能是我问题的另一种解决方案。
*:不是所有时间,而是一个季节;在 1-2 个服务器上每秒 50-200 个请求。
基于高通知率和性能,我应该继续使用这两个中的哪一个,还是有其他选择?
我试图使用SqlDependency类监视数据库表的更改.虽然我必须遗漏一些东西.我已经按照我在网上看到的所有示例进行了跟踪,并且我已经回顾了本网站上的所有问题.我只是看不到我错过的东西.以下是我在数据库上运行的初始命令,以启用服务代理并创建队列和服务.
CREATE QUEUE ScheduleChangeQueue
GO
CREATE SERVICE ScheduleChangeService ON QUEUE ScheduleChangeQueue ([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification])
GO
ALTER DATABASE [database] SET ENABLE_BROKER
Run Code Online (Sandbox Code Playgroud)
在C#方面,我创建了一个具有单个静态Setup方法的类,该方法被调用以启动该进程.这是代码:
public class SqlDependencyManager
{
private static bool DoesUserHavePermission()
{
var success = false;
try
{
Program.Log.Info("Retrieving SqlPermission to establish dependency...");
var clientPermission = new SqlClientPermission(System.Security.Permissions.PermissionState.Unrestricted);
// this will throw an error if the user does not have the permissions
clientPermission.Demand();
success = true;
Program.Log.Info("SqlPermission established. Continue setting up dependency.");
}
catch (Exception ex)
{
Program.Log.Error(ex, "SqlPermission not able to be established."); …Run Code Online (Sandbox Code Playgroud) 我有一个使用 SQLDependency 的应用程序。我想在插入新行时向用户显示插入到数据库表中的最新行。
当我的查询是一个简单的 select 语句时,这按预期工作,但鉴于我想显示最近插入的行,我将查询编写为SELECT TOP语句。这导致了多个异常。回顾这个问题后,我了解到这TOP对 SQLDependency 无效,因此我必须找到其他一些解决方案。
这让我想知道两件事:
A) SQLDependency 不支持TOP表达式的原因是什么?
B)我想出的解决方案是根据 id 对结果进行排序并只显示最后一个。这工作正常,但我的表目前只有很少的行。我正在使用数据集,所以我预计它会在插入更多行后变慢 - 这就是为什么我想将查询限制为仅最近的行。有一个更好的方法吗?
sqldependency ×13
sql-server ×9
c# ×7
.net ×2
signalr ×2
.net-3.5 ×1
ado.net ×1
asp.net ×1
sql ×1
sqlclr ×1
transactions ×1