Конференция "Базы" » Код ошибки Timeout expired в MS SQL Server. [MSSQL]
 
  • Дмитрий Тимохов (25.04.11 15:16) [0]
    Добрый день!

    Ситуация такова:
    1. Использую базу данных MS SQL Server.
    2. Для доступа использую ADODB.
    3. Использую провайдер SQLOLEDB

    Проблема:
    1. Хочу отлавливать момент, когда ADODB.Command завершается с ошибкой "Timeout expired" для целей последующей отладки подобных ситуаций.

    Что не получается:
    1. Не могу понять, как по ADODB.Error понять, что произошла эта ошибка (кроме как анализировать ADODB.Error.Description - но это же несерьезно).
    2. Не могу понять, откуда вообще брать коды ошибок, и что значат на самом деле ADODB.Error.NativeError и ADODB.Error.SqlState.

    Что делал:
    1. Поймал ошибку в runtime.
        Description: "Timeout expired"
        Native error: "0"
        Source: "Microsoft OLE DB Provider for SQL Server"
        SQLState: "HYT00"

    2. Я подумал, что HYT00 это код ошибки из Microsoft OLE DB Provider for SQL Server. Но не нашел такого.

    3. Потому я подумал, что это может код ошибки из стандарта SQL. Но там вроде согласно http://msdn.microsoft.com/en-us/library/aa937531%28SQL.80%29.aspx кодом ошибки для Timeout expired  является S1T00

    Вопросы:
    1. Какая ошибка то должна быть?
    2. Правильно я понимаю, что есть:
      а) Ошибки ADODB
      б) Ошибки сервера
      в) Ошибки OLEDB Provider'а
    Если да, то то где их всех отлавливать: в NativeError или SQLState?
    3. Где взять списки возможных ошибок?
  • Ega23 © (25.04.11 15:48) [1]

    > 1. Какая ошибка то должна быть?

    Походу EOleException


    >  в) Ошибки OLEDB Provider'а

    http://msdn.microsoft.com/en-us/library/ms190181.aspx


    > 3. Где взять списки возможных ошибок?

    Сейчас под рукой нет, см. в msdn и bol.
    Вообще я когда-то давно что-то подобное ловил, там у класса исключения ErrorCode должен быть.
  • Ega23 © (25.04.11 15:51) [2]
    Самое простое: тестовый проект, коннект к базе, отрубаешь сервер и вызываешь какой-нить запрос.
    try
     ADODataSet.Open;
    except on E: Exception do
     ShowMessage(E.ClassName);
    end;

    Вроде бы должен EOleError вернуть, у него код определённый есть. Выщучивай код и ищи в MSDN по нему (как в dec, так и в hex).
  • Дмитрий Тимохов (25.04.11 15:55) [3]
    Олегыч, ну я делал все это. Что нашел, то привел в вопросе.
    Почему вроде должен быть код ошибки в SQLState S1T00, а на самом деле HYT00...
  • Ega23 © (25.04.11 16:19) [4]

    > Олегыч, ну я делал все это. Что нашел, то привел в вопросе.


    Значит не так понял вопрос.

    ЕМНИП, там две разных ошибки. Одна - собственно сам процесс коннекта. Вторая - длительное выполнение команды.
    Возможно это именно та разница.
  • Дмитрий Тимохов (25.04.11 16:21) [5]
    Коннект нормальный. Я про выполнение запроса уже с помощью ADODB.Command.Execute. Меня интересует этот таймаут
  • Ega23 © (25.04.11 16:28) [6]

    > Коннект нормальный. Я про выполнение запроса уже с помощью
    > ADODB.Command.Execute. Меня интересует этот таймаут


    ааа.
    тогда см. ADODB.Command.CommandTimeout
  • Дмитрий Тимохов (25.04.11 16:50) [7]
    Олегыч, ты вопрос то прочти.

    Суть вопроса - по факту возвращается один код ошибки, а вроде должен быть другой, или я не понимаю что-то в структуре ошибок кодов ошибок...
  • OW © (25.04.11 17:02) [8]
    try
       
     except
      on E:Exception do
      begin
         EOleException(E).ErrorCode;  // comobj
      end;
     end;

    какой код?
  • Дмитрий Тимохов (25.04.11 17:08) [9]

    > какой код?

    //
    // MessageId: DB_E_ABORTLIMITREACHED
    //
    // MessageText:
    //
    //  Execution aborted because a resource limit has been reached; no
    //  results have been returned
    //
     DB_E_ABORTLIMITREACHED               = HResult($80040E31);
  • Дмитрий Тимохов (25.04.11 17:18) [10]
    Перефразирую вопрос - как бы вы гарантированно отлавливали timeout?
  • Ega23 © (25.04.11 17:21) [11]
  • OW © (25.04.11 17:22) [12]
    блокировки, видимо
    что за запрос?
  • Дмитрий Тимохов (25.04.11 17:29) [13]
    да запрос то не причем.
    я просто пытаюсь наладить логирование плохих запросов.
    специально поставил таймаут на минимум - многие отчеты вываливаются по таймауту.

    хочу понять, как определять, что это таймаут
  • Ega23 © (25.04.11 17:32) [14]

    > специально поставил таймаут на минимум - многие отчеты вываливаются
    > по таймауту.


    Ставь в 0, мало ли какой там отчет, или какая активность сервера?
    Вполне может быть, что решается через какой-нить
    DBCC DBREINDEX

  • Дмитрий Тимохов (25.04.11 17:41) [15]
    хороший совет. все равно, что - terminateprocess непокорным делать. ))
  • Ega23 © (25.04.11 17:46) [16]

    > хороший совет. все равно, что - terminateprocess непокорным
    > делать.


    Не, ну а что ты хочешь? Как можно оценить продолжительность выполнения запроса и выставить нужный timeout на конкретном сервере? Может быть дохлое железо, может быть много подключений, может быть старая индексация таблиц, может быть загрузка сети. Да что угодно может быть.
  • Дмитрий Тимохов (25.04.11 19:14) [17]
    блин ))) ты и MSDN так читаешь)))))

    я хочу услышать компетентный ответ, как МНЕ ОДНОЗНАЧНО ПОНЯТЬ, что выполнение метода ADODB.Command.Execute закончилось именно в ошибкой TIMEOUT EXPIRED, а не любой другой.
  • Дмитрий Тимохов (25.04.11 19:15) [18]
    Я пока проверяю SQLState и на равенство HYT00 и на S1T00... (по союзу OR, конечно, если что...)

    Вроде работает. Но удивляет, почему в доке одно (т.е. S1T00), а по факту HYT00...

    Может кто объяснит это? Возможно, что я не верно понимаю топологию кодов ошибок...
  • sniknik © (25.04.11 20:05) [19]
    procedure TForm1.Button1Click(Sender: TObject);
    var
     i: integer;
    begin
     try
       ADOCommand1.Execute;

       Memo1.Lines.Add('Ok');
     except
       on E: Exception do begin
         Memo1.Lines.Add(E.ClassName + ' : ' + E.Message);

         if E is EOleException then
           Memo1.Lines.Add('EOleException.ErrorCode : ' + IntToStr(EOleException(E).ErrorCode));

         with ADOConnection1.Errors do
           for i:= 0 to ADOConnection1.Errors.Count-1 do
             with Item[i] do
               Memo1.Lines.Add(IntToStr(NativeError {0}) + ':' +IntToStr(Number {-2147217871}) + ' : ' + Description);
       end;
     end;
    end;

 
Конференция "Базы" » Код ошибки Timeout expired в MS SQL Server. [MSSQL]
Есть новые Нет новых   [134431   +15][b:0][p:0.001]