Сообщение 7399 уровень 16 состояние 1

Обновлено: 06.07.2024

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

Возвращается через 30 секунд.

Локальный сервер - SQLSERVER 2008, удаленный - SQLSERVER 2000.

Мы сделали следующее безрезультатно:

  • Воссоздал сохраненный процесс.
  • sp_recompile для хранимого процесса
  • обновить статистику на dbo.accounts
  • удалил и пересоздал индексы на dbo.accounts
  • сбросил индекс на dbo.accounts и попробуй
  • DBCC FREEPROCCACHE и DBCC DROPCLEANBUFFERS на локальных и удаленных серверах
  • Перезагрузка удаленного сервера (непростой вариант на локальном)
  • Кто-нибудь может объяснить это странное поведение?
  • Любые предложения по другим вариантам его исправления?

Сколько строк возвращает репрезентативный запрос? Насколько быстрым / надежным является сетевое соединение между двумя серверами?

Возможно, что для передачи большого набора данных требуется слишком много времени (сверх фактического времени запроса). Вы можете увеличить значение тайм-аута.

Вы можете попытаться изменить настройку тайм-аута следующим образом:

Установите время ожидания удаленного входа в систему на 300 секунд:

Установите время ожидания удаленного запроса на 0 (бесконечное ожидание):

Обновление : вы правы, говоря, что это не размер данных или скорость соединения. В моей туманной памяти прозвенел звонок, и я вспомнил, где видел его: медленно в приложении, быстро в SSMS? (Проблема со связанными серверами). Это не перехват параметров, а сама статистика отсутствует (из-за разрешений), из-за чего используется неверный план запроса:

  • Вы можете добавить пользователей к роли db_ddladmin, но, поскольку это дает им право добавлять и удалять таблицы, это не рекомендуется.

  • По умолчанию, когда пользователи подключаются к удаленному серверу, они подключаются как они сами, но вы можете настроить сопоставление имени входа с помощью sp_addlinkedsrvlogin, чтобы пользователи сопоставлялись с учетной записью прокси, которая имеет членство в db_ddladmin. Обратите внимание, что эта учетная запись-посредник должна быть учетной записью SQL, поэтому это не вариант, если на удаленном сервере не включена проверка подлинности SQL. Это решение также несколько сомнительно с точки зрения безопасности, хотя оно лучше предыдущего предложения.

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

  • Конечно, вы могли бы использовать всю совокупность советов и планов, чтобы получить план, который вы хотите.

  • Наконец, вы должны спросить себя, нужен ли этот доступ к связанному серверу. Может быть, базы данных могут быть на одном сервере? Могут ли данные быть скопированы? Какое-то другое решение?

Отличный ответ и точно объяснил проблему, с которой я столкнулся, спасибо. Я бы добавил, что, согласно MSDN , начиная с SQL2012 SP1 и выше, пользователи с SELECT разрешениями смогут получить доступ, DBCC SHOW_STATISTICS что повысит производительность только для чтения на связанных серверах без ущерба для безопасности.

Что происходит, когда вы пытаетесь это сделать (то есть явно указывать, что следует запускать на удаленном сервере) ?:

Я подозреваю, что в вашем случае выше SQL Server просто извлекает всю таблицу с удаленного сервера, а затем выполняет запрос локально (я видел, что это случалось много раз в прошлом). Я предпочитаю быть явным (используя OPENQUERY или создавая SP на удаленном сервере), чтобы не было путаницы.

У меня есть две идеи, которые могут помочь. Я также расскажу вам, что мне не повезло с производительностью выполнения запросов к связанным серверам. Поэтому моя первая рекомендация - избегать этого, если можете.

Моя первая идея - установить хранимую процедуру в блок SQL Server 2000, указав ссылку на локальный сервер. Затем вы можете выполнить хранимую процедуру удаленно.

Если вы можете пойти по этому пути, это должно значительно улучшить производительность.

Моя вторая идея - получить приблизительный план запроса при запуске хранимой процедуры. Это показывает вам, что занимает так много времени? Одна потенциальная проблема заключается в том, что используемая учетная запись на связанном сервере может не иметь достаточных полномочий для получения статистики таблицы (вам нужно больше полномочий для связанного сервера, чем для локального сервера). И это может сделать запросы невероятно медленными. Вы можете прочитать больше об этой конкретной проблеме здесь .

Изучение задач, связанных с программированием баз данных на платформе MS SQL Server.

суббота, 30 августа 2014 г.

Особенности в работе функции openrowset

Как известно для запросов к Excel-файлам можно использовать функцию openrowset. Проверим работу этой функции на примере. Создадим файл 1.xlsx с таким содержанием:



Сохраним файл на рабочем столе. Убедимся в том, что сервер видит его:
exec xp_fileexist 'C:\Users\В\Desktop\1.xlsx'


Теперь попробуем сделать к нему запрос:

Поставщик OLE DB "Microsoft.ACE.OLEDB.12.0" для связанного сервера "(null)" сообщил об ошибке. Поставщик не предоставил данных об ошибке.

Не удалось получить строку от поставщика OLE DB "Microsoft.ACE.OLEDB.12.0" для связанного сервера "(null)".

Разберемся с причиной ошибки. Изначально я подключился к серверу на основе своей учетной записи Windows. При этом вхожу в роль sysadmin. Теперь подключимся на основе учетной SQL Server, под логином sa. Запускаем запрос и он успешно возвращает данные:



Оказывается, когда мы запускаем запрос то его результаты сохраняются в файле, который находится в директории переменной окружения temp или tmp. Посмотрим что это за директория. Для этого откроем список переменных среды:



Откроем папку C:\Users\В\AppData\Local\Temp и отсортируем ее содержимое по дате модификации. Сверху есть файл с именем tmp3BED.tmp. Откроем его при помощи Notepad:


В нем как раз результаты нашего запроса. Теперь можно сделать вывод, что при запуске openrowset с провайдером ACE под учетной записью Windows доступ к этой директории осуществляется именно при помощи учетной записи Windows. Если же мы подключаемся к серверу под учетной записью SQL Server, то доступ в Temp выполняется под учетной записью службы сервера. Если у учетной записи не хватает прав на работу с файлами, содержащими результаты работы запросов, то возникает ошибка.

понедельник, 25 августа 2014 г.

Получить состояние таблицы на определенное время

В MS SQL 2008 появилось новое средство слежения за данными: cdc, change data capture - отслеживание измененных данных. Этот механизм позволяет логировать изменения в таблице. Наибольший интерес представляет лог операций insert, update, delete. Однако кроме этого можно отслеживать и изменения в структуре таблицы. Рассмотрим на примере какие возможности есть у cdc и как с их помощью можно получить снэпшот таблицы на любой момент времени. Создадим для тестирования отдельную базу данных:

Создадим таблицу, которую мы наполним тестовыми данными:

Для включения cdc сперва требуется разрешить его на уровне всей базы. Для этого запускаем такой код:
exec sys . sp_cdc_enable_db

Теперь можно проверить, что для базы данных включено cdc:

where name = db_name ()

Следующим шагом нужно включить cdc на уровне таблицы:

@captured_column_list = 'i, k'

Когда процедура завершает работу, то для таблицы dbo.Logg создается специальная системная таблица, в которой фиксируются изменения от операций dml. Эта таблица содержится в создаваемой также схеме cdc. В этой схеме есть также таблица ddl_history для учета изменений в структуре таблицы. Также в схеме есть различные системные функции для просмотра информации об изменениях в таблице. Лучше пользоваться ими вместо запросов к системным таблицам.
Автоматически создается и роль (параметр @role_name), члены которой имеют доступ на просмотр информации об изменениях.
Параметр @filegroup_name отвечает за то, в какой файловой группе будет храниться лог изменений. В параметре @captured_column_list задается перечень столбцов, изменения в которых будут отслеживаться (по умолчанию null, то есть отслеживаются все столбцы).

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

Можно найти все таблицы, для которых включено cdc с помощью такого запроса:

where is_tracked_by_cdc = 1

Когда cdc включается для базы, то в SQL Agent создаются два задания: cdc.Watcher_capture, cdc.Watcher_cleanup. Первый следит за журналом транзакций для логирования изменений, второй - выполняет периодически очистку данных логов. По умолчанию история изменений хранится трое суток. При необходимости очистку можно выполнять самостоятельно с удобной для Вас прериодичностью. Для этого можно воспользоваться хранимой процедурой sys.sp_cdc_cleanup_change_table. Например, можно сделать такой вызов:
exec sys . sp_cdc_cleanup_change_table @capture_instance = 'Watcher' , @low_water_mark = 0x00000035000000A00006

В этом коде мы указываем, что очистка должна быть выполнена для определенного экземпляра системы отслеживания. И что удалиться должны все записи до указанного номера журнала транзакций. Ниже я расскажу о том, как получать такие номера.

Windows Vista Ultimate Windows Vista Enterprise 64-bit Edition Hyper-V Server 2008 Microsoft Hyper-V Server 2008 R2 Windows 7 Enterprise Windows 7 Home Basic Windows 7 Home Premium Windows 7 Service Pack 1 Windows 7 Ultimate Больше. Основные параметры

Проблемы

Рассмотрим следующий сценарий.

У вас есть экземпляр SQL Server, который установлен на компьютере под управлением Windows Vista или более поздней версии операционной системы.

На этом экземпляре SQL Server настройте связанный сервер к источнику данных с помощью поставщика OLEDB для источника данных OLEDB.

Поставщик OLE DB должен быть создан вне процесса SQL Server. Обычно это значение по умолчанию для большинства поставщиков OLEDB, кроме собственного клиента SQL. Это может управляться параметр Allow inprocess , которое может быть установлено с помощью свойства поставщика в Studio на доступ к данным SQL Server.

Безопасность связанный сервер настроен на использование быть сделаны с использованием текущего контекста безопасности имени входа параметр.

Примечание: В данном контексте непривилегированного пользователя является стандартный пользователь не принадлежит к группе привилегированный доступ на уровне Windows (например: Администраторы)

Причина

Обходное решение

Разверните узел Локальные политикии щелкните Назначение прав пользователя.

В правой области дважды щелкните Создание глобальных объектов.

В диалоговом окне Параметр локальной политики безопасности нажмите кнопку Добавить.

В диалоговом окне Выбор: пользователи или группы нажмите кнопку учетные записи пользователей, которые требуется добавить, нажмите кнопку Добавитьи нажмите кнопку ОК.

Состояние: Корпорация Майкрософт в настоящее время работает на устранение этой проблемы в будущих версиях продукта.

Вот что я пробовал:

Сначала я побежал .

Вслед за . без любви.

Я изменил код так, чтобы он читал Microsoft.ACE.OLEDB.12.0 , поскольку я тоже это видел, но по-прежнему не люблю.

Я также проверил разрешения C: \ Users \ MSSQLSERVER \ AppData \ Local \ Temp и C: Windows \ ServiceProfiles \ NetworkService \ AppData \ Local, которые предоставили полный доступ к следующим компонентам: Система, MSSQLSERVER и Администраторы, Сеть Сервис (по последнему слову).

До сих пор нет любви.

Наконец, я попытался перейти на 32-разрядную версию Microsoft Access Database Engine, которая по-прежнему не работает.

Читайте также: