Was sind die Einschränkungen von SqlDependency?

Ich benutze eine Tabelle als Nachrichtenwarteschlange und “Anmelden” für up für Updates mit einer SqlDependency. Überall, wo ich lese, sagen die Leute, dass sie nach den Einschränkungen suchen, aber nicht genau sagen, was sie sind. Von dem, was ich gesammelt habe, werden Sie Probleme haben, wenn der Tisch eine sehr hohe Aktualisierungshäufigkeit hat, glücklicherweise betrachte ich nur 10 bis 20 Werte pro Minute maximal.

Was sind die anderen Einschränkungen / Auswirkungen auf den SqlServer?

    Die vollständigste Liste, die ich ( von hier ) finden kann, ist wie folgt:

    • Die projizierten Spalten in der SELECT-statement müssen explizit angegeben werden, und Tabellennamen müssen mit zweiteiligen Namen qualifiziert werden. Beachten Sie, dass dies bedeutet, dass alle in der statement referenzierten Tabellen in derselben database sein müssen.
    • Die statement darf nicht den Stern ( ) oder Tabellenname verwenden. Syntax zum Angeben von Spalten.
    • Die statement darf keine unbenannten Spalten oder doppelte Spaltennamen verwenden.
    • Die statement muss auf eine Basistabelle verweisen.
    • Die statement darf nicht auf Tabellen mit berechneten Spalten verweisen.
    • Die projizierten Spalten in der SELECT-statement dürfen keine Aggregatausdrücke enthalten, es sei denn, die statement verwendet einen GROUP BY-Ausdruck. Wenn ein GROUP BY-Ausdruck bereitgestellt wird, kann die Auswahlliste die Aggregatfunktionen COUNT_BIG () oder SUM () enthalten. SUM () kann jedoch nicht für eine Nullwert-Spalte angegeben werden. Die statement darf HAVING, CUBE oder ROLLUP nicht angeben.
    • Eine projizierte Spalte in der SELECT-statement, die als einfacher Ausdruck verwendet wird, darf nicht mehr als einmal vorkommen.
    • Die statement darf keine PIVOT- oder UNPIVOT-Operatoren enthalten.
    • Die statement darf die Operatoren UNION, INTERSECT oder EXCEPT nicht enthalten.
    • Die statement darf nicht auf eine Sicht verweisen.
    • Die statement darf keines der folgenden Elemente enthalten: DISTINCT, COMPUTE oder COMPUTE BY oder INTO.
    • Die statement darf nicht auf globale Servervariablen verweisen (@@ Variablenname).
    • Die statement darf nicht auf abgeleitete Tabellen, temporäre Tabellen oder Tabellenvariablen verweisen.
    • Die statement darf nicht auf Tabellen oder Sichten von anderen databaseen oder Servern verweisen.
    • Die statement darf keine Unterabfragen, Outer-Joins oder Self-Joins enthalten.
    • Die statement darf nicht auf die großen Objekttypen verweisen: text, ntext und image.
    • Die statement darf die CONTAINS- oder FREETEXT-Volltextprädikate nicht verwenden.
    • Die statement darf keine Rowset-functionen verwenden, einschließlich OPENROWSET und OPENQUERY.
    • Die statement darf keine der folgenden Aggregatfunktionen verwenden: AVG, COUNT (*), MAX, MIN, STABW, STABW, VAR oder VARP.
    • Die statement darf keine nicht-deterministischen functionen verwenden, einschließlich Ranging- und Fensterfunktionen.
    • Die statement darf keine benutzerdefinierten Aggregate enthalten.
    • Die statement darf nicht auf Systemtabellen oder Sichten verweisen, einschließlich Katalogsichten und dynamischen Verwaltungssichten.
    • Die statement darf keine FOR BROWSE-Informationen enthalten.
    • Die statement darf nicht auf eine Warteschlange verweisen.
    • Die statement darf keine bedingten statementen enthalten, die sich nicht ändern können und keine Ergebnisse zurückgeben können (z. B. WHERE 1 = 0).
    • Die statement kann den READPAST-Sperrhinweis nicht angeben.
    • Die statement darf nicht auf eine Service Broker-QUEUE verweisen.
    • Die Aussage darf nicht auf Synonyme verweisen.
    • Die statement darf keinen Vergleich oder Ausdruck basierend auf doppelten / echten Datentypen enthalten.
    • Die statement darf nicht den TOP-Ausdruck verwenden.

    Zusätzliche Referenz (en):

    • Mit Anfragenbenachrichtigungen arbeiten

    Für alle anderen, die darüber nachdenken, SqlDependency zu verwenden, um Benachrichtigungen über Änderungen zu erhalten, verwende ich diesen Ansatz in der Produktion, und ich finde Probleme damit. Ich untersuche es, um zu sehen, ob die Probleme mit meinem Code zusammenhängen, aber die Hauptprobleme sind:

    • Wenn Sie mehrere Änderungen in schneller Folge auslösen, erhalten Sie nicht immer die entsprechende Anzahl von Ereignissen, die den Code durchlaufen. In meinem Code, wenn 2 neue Datensätze nacheinander eingefügt werden, bekomme ich nur die eine Benachrichtigung (für die letzte).

    • Es gibt keine Möglichkeit, den hinzugefügten Datensatz zu kennen. Wenn Sie also einen neuen Datensatz hinzufügen und der Code zum Empfangen der Benachrichtigung ausgetriggers wird, gibt es im Code keine Möglichkeit, die ID dieses neuen Datensatzes zu kennen. Daher müssen Sie die database danach abfragen.

    Einen Tag damit verbracht, ein Problem zu verfolgen, bei dem SQL Service Broker nicht funktionierte, referenzierte die Grundursache die database in der gespeicherten Prozedur.

    Zum Beispiel funktioniert diese select in SQL Management Studio einwandfrei:

     select [MyColumn] from [MyDatabase].[MySchema].[MyTable] 

    Dies wird jedoch von SQL Service Broker abgelehnt, da wir auf die database in der SqlDependency statement SqlDependency und der Callback von SqlDependency mit Invalid in SqlNotificationEventArgs e , siehe http://msdn.microsoft.com/en-us/library/ ms189308.aspx .

    Durch das Ändern der SQL, die in SqlDependency an die folgende statement übergeben wurde, wurde der Fehler behoben:

     select [MyColumn] from [MySchema].[MyTable] 

    Aktualisieren

    Das obige Beispiel ist nur eine von vielen, vielen Einschränkungen für die SQL-statement, von der SQL Service Broker abhängt. Eine vollständige Liste der Einschränkungen finden Sie unter Einschränkungen der Sql-Abhängigkeit .

    Der Grund? Die SQL-statement, die SQL Service Broker verwendet, wird im Hintergrund in statementen konvertiert, um das SQL-Transaktionsprotokoll auf Änderungen in der database zu überwachen. Diese Überwachung wird im core von SQL Server ausgeführt, wodurch sie extrem schnell ist, wenn es darum geht, Änderungen an Tabellen zu erkennen. Diese Geschwindigkeit ist jedoch mit Kosten verbunden: Sie können nicht jede SQL-statement verwenden, Sie müssen eine statement verwenden, die in statementen zur Überwachung des SQL-Transaktionsprotokolls konvertiert werden kann.

    Beachten Sie, dass Sie keinen Nolock-Hinweis in der gespeicherten Prozedur verwenden können oder dass die Abhängigkeit ständig ungültig bleibt und daher jeder Cache, den Sie daran anlegen, die database permanent erneut abfragt.

     with (NOLOCK) 

    Dies scheint nicht in der Dokumentation erwähnt zu werden (soweit ich das beurteilen kann)

    Die folgenden SET-Optionen sind vor dem Prozedurskript erforderlich

     SET ANSI_NULLS ON SET ANSI_PADDING ON SET ANSI_WARNINGS ON 

    Andere haben argumentiert, dass diese SET-Optionen auch erforderlich sind, aber ich glaube nicht, dass sie es sind. Es ist trotzdem eine gute Idee, das so einzustellen.

     SET CONCAT_NULL_YIELDS_NULL ON SET QUOTED_IDENTIFIER ON SET NUMERIC_ROUNDABORT OFF SET ARITHABORT ON 

    Ein anderes großes Problem, das ich mit dieser Technologie habe: die Notwendigkeit für die Teilnehmerverbindung, um Create Procedure-Berechtigungen zu haben. Die Web-Service-Schicht meiner momentan aktiven Anwendung läuft als eingeschränkter Benutzer. Um Benachrichtigungen mit SQLDependency einzurichten, müsste ich diesen Benutzer zum Erstellen von Procs öffnen. Klingt wie ein ziemlich guter Schritt auf dem Weg des Besitzens.

    Um diese Einschränkungen zu umgehen, können Sie versuchen, die SqlTableDependency zu verwenden. Sehen Sie sich http://www.sqltabledependency.it an