49

テーブルをメッセージ キューとして使用し、SqlDependency を使用して更新に「サインアップ」しています。私が読んだどこでも、人々は「それの限界に気をつけてください」と言っていますが、彼らが何であるかについては具体的に述べていません. 私が収集したことから、テーブルの更新頻度が非常に高い場合に問題が発生します。幸いなことに、私は毎分最大 10 ~ 20 の値しか見ていません。

SqlServer のその他の制限/影響は何ですか?

4

7 に答える 7

69

私が見つけることができる最も完全なリスト (ここから) は次のとおりです。

  • SELECT ステートメント内の射影された列は明示的に指定する必要があり、テーブル名は 2 部構成の名前で修飾する必要があります。これは、ステートメントで参照されるすべてのテーブルが同じデータベースにある必要があることを意味することに注意してください。
  • ステートメントでは、アスタリスク (*) または table_name.* 構文を使用して列を指定することはできません。
  • ステートメントでは、名前のない列や重複する列名を使用できません。
  • ステートメントはベース テーブルを参照する必要があります。
  • ステートメントは、計算列を含むテーブルを参照してはなりません。
  • ステートメントが GROUP BY 式を使用しない限り、SELECT ステートメントの射影された列に集計式を含めることはできません。GROUP BY 式を指定すると、選択リストに集計関数 COUNT_BIG() または SUM() が含まれる場合があります。ただし、NULL 許容列には SUM() を指定できません。このステートメントでは、HAVING、CUBE、または ROLLUP を指定することはできません。
  • 単純な式として使用される SELECT ステートメント内の射影された列は、複数回出現してはなりません。
  • ステートメントに PIVOT または UNPIVOT 演算子を含めてはなりません。
  • ステートメントには、UNION、INTERSECT、または EXCEPT 演算子を含めてはなりません。
  • ステートメントはビューを参照してはなりません。
  • ステートメントには、DISTINCT、COMPUTE、COMPUTE BY、または INTO を含めることはできません。
  • ステートメントは、サーバー グローバル変数 (@@variable_name) を参照してはなりません。
  • ステートメントは、派生テーブル、一時テーブル、またはテーブル変数を参照してはなりません。
  • ステートメントは、他のデータベースまたはサーバーからのテーブルまたはビューを参照してはなりません。
  • ステートメントには、サブクエリ、外部結合、または自己結合を含めることはできません。
  • ステートメントは、ラージ オブジェクト タイプ (text、ntext、および image) を参照してはなりません。
  • ステートメントでは、CONTAINS または FREETEXT 全文述語を使用してはなりません。
  • ステートメントでは、OPENROWSET や OPENQUERY などの行セット関数を使用してはなりません。
  • ステートメントでは、次の集約関数を使用してはなりません: AVG、COUNT(*)、MAX、MIN、STDEV、STDEVP、VAR、または VARP。
  • ステートメントでは、ランキング関数やウィンドウ関数など、非決定論的な関数を使用してはなりません。
  • ステートメントには、ユーザー定義の集計を含めることはできません。
  • ステートメントは、カタログ ビューや動的管理ビューを含むシステム テーブルまたはビューを参照してはなりません。
  • ステートメントに FOR BROWSE 情報を含めてはなりません。
  • ステートメントはキューを参照してはなりません。
  • ステートメントには、変更できず、結果を返すことができない条件ステートメント (WHERE 1=0 など) を含めることはできません。
  • ステートメントは READPAST ロック ヒントを指定できません。
  • ステートメントは Service Broker QUEUE を参照してはなりません。
  • ステートメントは同義語を参照してはなりません。
  • ステートメントには、double/real データ型に基づく比較または式を含めてはなりません。
  • ステートメントで TOP 式を使用してはなりません。

追加の参照:

于 2011-09-28T19:40:18.480 に答える
13

これに加えて、SqlDependency を使用して変更に関する通知を受け取ることを考えている他の人のために、私はこのアプローチを本番環境で使用しており、問題を見つけています。問題が私のコードに関連しているかどうかを調べていますが、主な問題は次のとおりです。

  • 複数の変更を立て続けに実行すると、常に同じ数のイベントがコードに渡されるとは限りません。私のコードでは、2 つの新しいレコードが次々に挿入された場合、(最後のレコードに対して) 1 つの通知しか受け取りません。

  • 追加されたレコードを知る方法はありません。そのため、新しいレコードを追加し、コードが起動して通知を受信した場合、コードにはその新しいレコードの ID を知る方法がないため、データベースにクエリを実行する必要があります。

于 2012-06-12T10:32:30.457 に答える
10

SQL Service Broker が機能しないという問題を追跡するのに 1 日を費やしましたが、根本的な原因はストアド プロシージャでのデータベースの参照でした。

たとえば、これselectは SQL Management Studio で正常に機能します。

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

ただし、select ステートメントでデータベースを参照しているため、これは SQL Service Broker によって拒否され、 からのコールバックSqlDependencyInvalidinSqlNotificationEventArgs e返されます。

SqlDependency に渡される SQL を次のステートメントに変更すると、エラーが解消されました。

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

アップデート

上記の例は、SQL Service Broker が依存する SQL ステートメントに対する非常に多くの制限の 1 つにすぎません。制限の完全なリストについては、「SqlDependency の制限とは」を参照してください。

理由?SQL Service Broker が使用する SQL ステートメントは、バックグラウンドで、 SQL トランザクション ログでデータベースの変更を監視するための命令に変換されます。この監視は SQL Server のコアで実行されるため、テーブルへの変更の検出に関しては非常に高速です。ただし、この速度には代償が伴います。SQL ステートメントだけを使用することはできません。SQL トランザクション ログを監視するには、命令に変換できるステートメントを使用する必要があります。

于 2014-01-31T09:23:58.163 に答える
5

ストアド プロシージャで nolock ヒントを使用できないことに注意してください。そうしないと、依存関係が常に無効なままになるため、作成したキャッシュはデータベースに対して永続的に再クエリを実行することになります。

with (NOLOCK) 

これはドキュメントに記載されていないようです (私が知る限り)。

プロシージャ スクリプトの前に、次の SET オプションが必要です。

SET ANSI_NULLS ON
SET ANSI_PADDING ON  
SET ANSI_WARNINGS ON

これらの SET オプションも必須であると主張する人もいますが、そうではないと思います。とにかく、このように設定することをお勧めします。

SET CONCAT_NULL_YIELDS_NULL ON 
SET QUOTED_IDENTIFIER ON 
SET NUMERIC_ROUNDABORT OFF 
SET ARITHABORT ON
于 2015-04-29T15:32:09.603 に答える
3

これらの制限を克服するには、SqlTableDependency を使用してみてください。www.sqltabledependency.it をご覧ください。

于 2016-10-24T20:57:33.080 に答える
3

このテクノロジーに関して私が抱えているもう 1 つの大きな問題は、サブスクライバー接続に Create Procedure パーミッションが必要なことです。現在、私のアプリケーションの Web サービス層は、制限されたユーザーとして実行されています。SQLDependency を使用して通知を設定するには、そのユーザーを開いて procs を作成する必要があります。オーナーになる道のりに沿ったかなり良いステップのように思えます。

于 2013-12-02T20:16:21.190 に答える
1

Service Broker を使用します。したがって、管理されていない SQL Azure インスタンスでは機能しません。そのため、SQL Azure を使用している場合、または使用する可能性がある場合は注意してください。

https://docs.microsoft.com/en-us/azure/sql-database/sql-database-features

サービスブローカー

単一データベースとエラスティック プールでサポート:

いいえ

マネージド インスタンスによるサポート:

はい。ただし、インスタンス内のみです。Service Broker の違いを参照してください

したがって、すべての環境で使用できない限り、おそらく適切ではありません!

于 2019-06-26T22:14:55.343 に答える