#sql-server #tsql
#sql-сервер #tsql #sql-server
Вопрос:
У меня есть SQL-запрос, и он время от времени завершается ошибкой. Это означает, что запрос в большинстве случаев выполняется нормально. После сбоя запроса, если я выполняю его снова с некоторой задержкой, он выполняется успешно при том же выполнении.
Пожалуйста, обратите внимание, что в таблицах, используемых в запросе, нет изменений между сценариями успешного выполнения и сбоя. Они точно такие же. Как упоминалось ниже, запрос объединяет пару таблиц, и результат запроса должен быть пустым. Но иногда ADO выдает ошибку.
Как можно выяснить основную причину проблемы?
Я намеренно опустил некоторые детали, поскольку мне интересно узнать общий подход к решению проблем при сбоях SQL-запроса.
Вот некоторые подробности, которые также следует знать о любых конкретных альтернативных подходах.
- Microsoft SQL Server 2008
- Использование запроса соединяет две таблицы
- Запрос передается из .NET через interop, а COM-компонент обрабатывает ADO для выполнения запроса.
- Информация об ошибке 0x80004005(-2147467259) [DBNETLIB][ConnectionOpen (Connect()).]SQL Server не существует или доступ запрещен.
Обновить:
Для этой конкретной проблемы я решил, что у клиента заканчиваются доступные TCP-порты. Согласно настройкам по умолчанию, 5000 портов — это максимальное количество TCP-портов. В моем случае ADO создает неявные соединения, которые создают TCP-порт каждый раз, когда выполняется запрос.
netstat
показал мне, что количество открытых портов резко увеличилось, когда я запустил рабочий процесс. Примерно на 4000 портах запрос завершается ошибкой (0-1023 — зарезервированные порты). Ответ от Джибкова Добрева в здесь указал мне правильное направление.
Комментарии:
1. Под «сбоем» вы подразумеваете «он возвращает неправильные данные» или «он возвращает сообщение об ошибке вместо каких-либо данных»?
2. -1 — Скорее всего, проблема взаимоблокировки или тайм-аут, связанный с блокировкой. К сожалению, OP does it funny заставляет нас гадать и не хочет получать ответ — в противном случае он выдал бы сообщение об ошибке. Отклонено как неполное.
3. @Mark Bannister: Результат запроса пустой, что правильно, но я получаю неверный HRESULT от ADO 0x80004005 (-2147467259) [DBNETLIB][ConnectionOpen (Connect()).]SQL Server не существует или доступ запрещен.
4. @TomTom: зачем человеку утруждать себя написанием вопроса, если его не интересует ответ? Я не предоставил сообщение об ошибке, потому что хотел знать, каков общий подход к такого рода проблемам; сообщение об ошибке привело бы к «вам просто нужно сделать это для решения этой проблемы», чего я здесь не хотел.
5. Не забудьте отметить ответ как принятый, если вы получили нужную информацию
Ответ №1:
Прочитайте сообщение об ошибке!
На самом деле запрос «завершается ошибкой» только по нескольким причинам:
- нарушение уникальности, проверки или другого ограничения
- проблема с типом данных (несоответствие, переполнение)
- ???
Во время анализа будут обнаружены неправильные или противоречивые агрегированные данные или синтаксис. Но…
- в случае динамического SQL это может привести к «сбою», потому что это синтаксически неправильно
Это может быть медленным или выдавать неправильные данные, но это не «сбой» как таковой.
Редактировать:
Это не ошибка запроса: это ошибка подключения, не связанная с какой-либо командой SQL.
Как правило, теперь вам нужно решить, связано ли это с одним клиентом или это общая проблема
Комментарии:
1. вы правы. это не сбой запроса. это ошибка подключения. спасибо за ваши предложения.
Ответ №2:
«Общий подход к решению проблем» при сбое SQL-запроса такой же, как и при любом другом сбое кода:
- Определите, что он делает.
- Определите, что он должен делать.
- Определите, почему это отличается.
- Исправьте это.
РЕДАКТИРОВАТЬ: после предоставления более подробной информации в следующей статье базы знаний Microsoft: http://support.microsoft.com/kb/328306 рассматриваются возможные причины и способы решения этой проблемы.
Комментарии:
1. Спасибо. Я подробнее остановлюсь на деталях.
Ответ №3:
В статье KB «потенциальные причины» отсутствует статья, которая решила эту проблему для меня — «вы не можете получить доступ к базе данных SQL Server с помощью поставщика OLE DB для SQL Server, когда ваше приложение находится в сценарии с высокой нагрузкой»http://support.microsoft.com/kb/907264
В этой ситуации — процесс выполняется некоторое время, извлекая данные нормально, прежде чем завершиться сбоем с ошибкой.
Запуск ‘netstat -an’ покажет все IP-адреса / порты, открытые во время выполнения процесса. Для меня они находятся на уровне 20 или около того, пока не будет достигнут определенный блок кода … затем быстро увеличиваются до 4000 , и приложение завершается сбоем
Комментарии:
1. Это именно то, что произошло со мной в этом конкретном случае. Исчерпан лимит портов. По соображениям безопасности Windows ограничивает его (5000). Я использовал набор записей на стороне клиента, который был подходящим и решил проблему за меня.
Ответ №4:
Вы можете:
Запустите sql profiler для захвата запроса, убедитесь, что запрос правильно сформирован. Вы можете оставить трассировку запущенной столько, сколько захотите.
Запустите захваченный запрос в management Studio, sql server выдаст все ошибки, с которыми он столкнется.
если это все еще не помогает, возможно, разделите запрос на многоступенчатую хранимую процедуру.. записывая значения / параметры и т.д. состояний в таблицу / файл журнала перед каждым шагом .. чтобы вы могли определить некоторые общие факторы при сбое.
Возможно, даже зарегистрируйте созданный запрос и результат в файле журнала из .net и сравните разницу в запросах.
В зависимости от того, как вы настроили подключение к данным, Visual Studio также позволяет facilty пошагово выполнять хранимые процедуры.
Комментарии:
1. Это был бы подход, если бы постоянно возникали какие-то проблемы с конкретным запросом; но мой запрос в большинстве случаев выполняется успешно, и периодически он завершается неудачей. Задаетесь вопросом о том, как устранить проблемы такого рода.
2. Всегда ли запрос идентичен? или могут ли параметры, содержащиеся в нем, измениться? если они могут, вам нужно записать сбойный запрос .. как-нибудь протоколировать его. если это не изменяется, то причиной этого является среда, будь то блокировка записей в БД, разрыв соединения с БД, тайм-аут из-за занятости сервера и т.д., Которые будет сложнее изолировать.. может быть, запустить трассировку и посмотреть, сможете ли вы обнаружить неудачный запрос и сравнить его со статистикой сервера. Вам необходимо изолировать параметры вокруг запроса.
3. Да, это сложная сторона. Это среда. Хотя это параметризованный запрос. Но я пришел к выводу, что сбой не относится к каким-либо конкретным значениям.
Ответ №5:
Специфично для
0x80004005(-2147467259) [DBNETLIB][ConnectionOpen (Connect()).]SQL Server не существует или доступ к нему запрещен.
похоже, это хорошая отправная точка для расследования: возможные причины сообщения об ошибке «SQL Server не существует или доступ запрещен»