Каковы ограничения SqlDependency - PullRequest
       19

Каковы ограничения SqlDependency

40 голосов
/ 28 сентября 2011

Я использую таблицу в качестве очереди сообщений и "подписываюсь" на получение обновлений с помощью SqlDependency.Везде, где я читаю, люди говорят, что следите за ограничениями, но конкретно не говорите, что они есть.Из того, что я понял, у вас будут проблемы, когда таблица будет иметь очень высокую частоту обновления, к счастью, я смотрю только на 10 - 20 значений в минуту максимум.

Какие другие ограничения / влияние на SqlServer?

Ответы [ 7 ]

61 голосов
/ 28 сентября 2011

Наиболее полный список, который я могу найти ( отсюда ), выглядит следующим образом:

  • Проецируемые столбцы в операторе SELECT должны быть указаны явно, а имена таблиц должны содержать имена из двух частей. Обратите внимание, что это означает, что все таблицы, на которые есть ссылки в операторе, должны находиться в одной базе данных.
  • Оператор не может использовать звездочку () или имя_таблицы. синтаксис для указания столбцов.
  • Оператор не может использовать безымянные столбцы или повторяющиеся имена столбцов.
  • Оператор должен ссылаться на базовую таблицу.
  • Оператор не должен ссылаться на таблицы с вычисляемыми столбцами.
  • Проецируемые столбцы в операторе SELECT могут не содержать агрегатных выражений, если только оператор не использует выражение GROUP BY. Когда предоставляется выражение GROUP BY, список выбора может содержать агрегатные функции COUNT_BIG () или SUM (). Тем не менее, SUM () не может быть указан для столбца, допускающего значение NULL Оператор не может указывать HAVING, CUBE или ROLLUP.
  • Проецируемый столбец в операторе SELECT, который используется как простое выражение, не должен появляться более одного раза.
  • Оператор не должен включать операторов PIVOT или UNPIVOT.
  • Оператор не должен включать операторы UNION, INTERSECT или EXCEPT.
  • Оператор не должен ссылаться на представление.
  • Оператор не должен содержать ничего из следующего: DISTINCT, COMPUTE или COMPUTE BY или INTO.
  • Оператор не должен ссылаться на глобальные переменные сервера (@@ variable_name).
  • Оператор не должен ссылаться на производные таблицы, временные таблицы или переменные таблиц.
  • Оператор не должен ссылаться на таблицы или представления из других баз данных или серверов.
  • Оператор не должен содержать подзапросов, внешних объединений или самостоятельных объединений.
  • Оператор не должен ссылаться на большие типы объектов: текст, текст и изображение.
  • Оператор не должен использовать полнотекстовые предикаты CONTAINS или FREETEXT.
  • Оператор не должен использовать функции набора строк, включая OPENROWSET и OPENQUERY.
  • Оператор не должен использовать ни одну из следующих агрегатных функций: AVG, COUNT (*), MAX, MIN, STDEV, STDEVP, VAR или VARP.
  • Оператор не должен использовать недетерминированные функции, включая функции ранжирования и управления окнами.
  • Оператор не должен содержать определенные пользователем агрегаты.
  • Оператор не должен ссылаться на системные таблицы или представления, включая представления каталога и представления динамического управления.
  • Выписка не должна содержать информацию FOR BROWSE.
  • Оператор не должен ссылаться на очередь.
  • Оператор не должен содержать условных операторов, которые не могут изменяться и не могут возвращать результаты (например, WHERE 1 = 0).
  • В операторе нельзя указать подсказку блокировки READPAST.
  • Заявление не должно ссылаться на QUEUE компонента Service Broker.
  • Оператор не должен ссылаться на синонимы.
  • Оператор не должен иметь сравнения или выражения, основанного на двойных / реальных типах данных.
  • Оператор не должен использовать выражение TOP.

Дополнительные ссылки:

12 голосов
/ 12 июня 2012

В дополнение к этому, для тех, кто думает об использовании SqlDependency для получения уведомлений об изменениях, я использую этот подход в работе и нахожу проблемы с ним.Я смотрю на это, чтобы увидеть, связаны ли проблемы с моим кодом, но основные проблемы:

  • Если вы запускаете несколько изменений в быстрой последовательности, вы не всегда получаетеэквивалентное количество событий, поступающих в код.В моем коде, если две новые записи вставляются одна за другой, я получаю только одно уведомление (для последней).

  • Нет способа узнать, какая запись быладобавлено.Поэтому, если вы добавляете новую запись, и код запускается для получения уведомления, в коде нет способа узнать идентификатор этой новой записи, поэтому вам нужно запросить ее у базы данных.

9 голосов
/ 31 января 2014

Потратил день на поиски проблемы с неработающим SQL Service Broker, основной причиной которой была ссылка на базу данных в хранимой процедуре.

Например, это select отлично работает в SQL Management Studio:

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

Однако это отклонено SQL Service Broker, поскольку мы ссылаемся на базу данных в операторе выбора, и обратный вызов из SqlDependency возвращается с Invalid в SqlNotificationEventArgs e, см. http://msdn.microsoft.com/en-us/library/ms189308.aspx.

Изменение SQL, переданного в SqlDependency, для следующего оператора устранило ошибку:

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

Обновление

Приведенный выше пример является лишь одним из множества ограничений оператора SQL, от которых зависит SQL Service Broker. Полный список ограничений см. Каковы ограничения SqlDependency .

причина? Оператор SQL, который использует SQL Service Broker, за кадром преобразуется в инструкции для отслеживания изменений в базе данных Журнал транзакций SQL . Этот мониторинг выполняется в ядре SQL Server, что делает его чрезвычайно быстрым, когда дело доходит до обнаружения изменений в таблицах. Однако эта скорость обходится дорого: вы не можете использовать только какой-либо оператор SQL, вы должны использовать тот, который можно преобразовать в инструкции, чтобы отслеживать Журнал транзакций SQL .

5 голосов
/ 29 апреля 2015

Обратите внимание, что вы не можете использовать подсказку 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
3 голосов
/ 03 декабря 2013

Еще одна большая проблема, с которой я столкнулся при использовании этой технологии: необходимость подключения подписчика для получения разрешений на создание процедур.Слой веб-службы моего приложения на данный момент работает как пользователь с ограниченными правами.Чтобы настроить уведомления с помощью SQLDependency, мне нужно открыть этого пользователя для создания процедур.Звучит как довольно хороший шаг на пути к тому, чтобы стать владельцем.

2 голосов
/ 24 октября 2016

Чтобы преодолеть эти ограничения, вы можете попробовать использовать SqlTableDependency.Взгляните на www.sqltabledependency.it

0 голосов
/ 27 июня 2019

Используется Service Broker.Поэтому он не будет работать на неуправляемых экземплярах SQL Azure.Поэтому будьте осторожны, если вы используете SQL Azure или когда-либо можете.

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

Компонент Service Broker

Поддерживается отдельными базами данных и эластичными пулами:

Нет

Поддерживается управляемыми экземплярами:

Да, но только внутри экземпляра.См. Отличия Service Broker

Так что, вероятно, не подходит, если только ваша среда не может его использовать!

...