代码之家  ›  专栏  ›  技术社区  ›  Ahmer Ali Ahsan

SqlDependency无法使用现有数据库

  •  0
  • Ahmer Ali Ahsan  · 技术社区  · 7 年前

    我将signer与SqlDependency一起使用。我的代码可以正常工作,它可以显示我想要的实时结果。但问题是它正在运行我新创建的数据库。如果我将数据库更改为旧数据库,SqlDependency将停止工作,并且无法在数据库表上检测到更改。

    下面是我的代码:

    #region SignalRMethods
        [System.Web.Script.Services.ScriptMethod()]
        [System.Web.Services.WebMethod(EnableSession = true)]
        public GlobalApplicationError[] GetErrorsList()
        {
            var cs = "Data Source=.;Initial Catalog=NotifyDB;Integrated Security=True";
            using (var connection = new SqlConnection(cs))
            {
                connection.Open();
                SqlDependency.Start(cs);
                using (SqlCommand command = new SqlCommand(@"SELECT  [Form_Name],[Message],[Prepared_By_Date] FROM [GlobalApplicationError]", connection))
                {
                    // Make sure the command object does not already have
                    // a notification object associated with it.
    
                    SqlDependency dependency = new SqlDependency(command);
                    dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
    
                    if (connection.State == ConnectionState.Closed)
                        connection.Open();
    
                    using (var reader = command.ExecuteReader())
                        return reader.Cast<IDataRecord>()
                            .Select(x => new GlobalApplicationError()
                            {
                                Form_Name = x["Form_Name"].ToString(),
                                Message = x["Message"].ToString(),
                                Prepared_By_Date = Convert.ToDateTime(x["Prepared_By_Date"])
                            }).ToList().ToArray();
                }
            }
        }
    
        private static void dependency_OnChange(object sender, SqlNotificationEventArgs e)
        {
            MyHub.Show();
        }
        #endregion
    

    上面的代码在数据库上完美地工作 NotifyDB 但不是在我现有的 eprocure 如果我更改连接字符串中的数据库。由于我正在使用ASMXWeb服务,所以我总是更新web服务的引用。另外,我在两个数据库上都将enable_broker设置为true。

    数据库屏幕截图:

    NotifyDB

    enter image description here

    电子文档

    enter image description here

    enter image description here

    输出

    enter image description here

    请让我知道我在代码中做错了什么。提前谢谢。

    2 回复  |  直到 7 年前
        1
  •  3
  •   Ahmer Ali Ahsan    7 年前

    让我们结束这个。在网上进行了一些头脑风暴后,我成功地找到了答案。

    sys.transmission_queue 使用以下查询:

    select * from sys.transmission_queue

    我们的通知很可能会在那里,因为无法送达而保留。传输状态可以解释为什么会发生这种情况。

    我发现有以下错误:

    错误:15517,状态:1。无法作为数据库主体执行,因为主体“dbo”不存在

    通过谷歌搜索,找到以下有用的链接:

    Troubleshooting SQL Server Error 15517

    EXEC sp_MSForEachDB 
    'SELECT ''?'' AS ''DBName'', sp.name AS ''dbo_login'', o.name AS ''sysdb_login''
    FROM ?.sys.database_principals dp
    LEFT JOIN master.sys.server_principals sp
    ON dp.sid = sp.sid
    LEFT JOIN master.sys.databases d 
    ON DB_ID(''?'') = d.database_id
    LEFT JOIN master.sys.server_principals o 
    ON d.owner_sid = o.sid
    WHERE dp.name = ''dbo'';';
    

    通过这样做,我找到了几个sys.databases说有所有者的数据库。但是,当我从数据库的sys.database_主体检查它时,SID与dbo不匹配。我用于dbo_登录的列返回空。这是问题的明显迹象。您还可能会看到dbo_登录和sysdb_登录之间不匹配。似乎只要dbo_登录名与合法登录名匹配,就不会生成错误。我在我的一台服务器上的一些数据库上发现了这一点。虽然它现在没有引起问题,但我会设法纠正不匹配。

    更正错误:

    更正错误的最简单方法是对数据库使用ALTER AUTHORITION,该数据库的登录名与dbo匹配为NULL。简单到:

    ALTER AUTHORIZATION ON DATABASE::eprocure TO sa;

        2
  •  0
  •   Ramesh César Landesa    7 年前

    请确保查询通知&已启用Service broker并授予IIS标识的权限。

    启用以下功能的步骤: https://techbrij.com/database-change-notifications-asp-net-signalr-sqldependency

    要检查是否启用了ServiceBroker,请执行以下语句

    SELECT name, is_broker_enabled FROM sys.databases
    

    启用ServiceBroker

    ALTER DATABASE <<DatabaseName>> SET ENABLE_BROKER
    

    向用户授予权限

    GRANT SUBSCRIBE QUERY NOTIFICATIONS TO “<<USERIDENTITY>”