Текст ошибки BDE искажается и обрезается

Руслан Иванофф
Дата: 09.07.2009 16:48:08
Здравствуйте!

Давно существует проблема с ошибками BDE, решение которой найти не могу.
Суть ее в следующем!
Используется связка Delphi 2007 – BDE – MSSQL

В клиенте удаляется запись, на которую есть ссылка из других таблиц. Получаем ошибку нарушения ссылочной целостности:

The DELETE statement conflicted with the REFERENCE constraint "FK_Test2_Test3". The conflict occurred in database "Test", table "dbo.Test2", column 'Id'.

Это выдает сам MSSQL. А вот обработка ошибки в клиенте приводит к тому, что на выходе получается текст ошибки:

Master record missing.
The DELETE statement conflicted with the REFERENCE constraint "FK_Test2_Test3". The conflict occurred in database "Test",
General SQL error.
table � G

Разложение ошибки в коде типа:

 if e is EDBEngineError then begin

     for i := 0 to EDBEngineError(e).ErrorCount-1 do begin
       Memo1.Lines.Add(IntToStr(EDBEngineError(e).Errors[i].ErrorCode) + ' - ' + EDBEngineError(e).Errors[i].Message);
       Memo1.Lines.Add('');
     end;

end;

Возвращает следующие строки:

9733 - Master record missing.

13059 - The DELETE statement conflicted with the REFERENCE constraint "FK_Test2_Test3". The conflict occurred in database "Test",

13059 - table � G

Т.е. видно, что оригинальное сообщение об ошибке просто обрезается. Более того. Видно, что третья строка ошибки просто искажается другой информацией, т.к. после слова table появляется псевдографика и посторонние символы, которые при каждом запуске программы будут разные.

Существует ли способ побороть проблему обрезания текста ошибки? Очень не удобно, когда скажем длинные сообщения, возвращаемые MSSQL режутся до 120-130 символов.

Для верности проверил работу ADO. Там все работает как часы. Текст ошибки возвращается полный. Все корректно.

Спасибо!

P.S. Меньше всего я бы хотел здесь увидеть совет переходить на ADO. Приложение большое, написано давно, работает отлично и переписываться не будет. Просто хочется решить проблему с текстами ошибок. Перехват ошибок по коду и замена их на тексты на понятном языке не решает проблему, т.к. хочется в т.ч. видеть и техническую информацию.
Кроик Семён
Дата: 10.07.2009 12:22:42
автор
Используется связка Delphi 2007 – BDE – MSSQL


нда...
Anatoly Podgoretsky
Дата: 10.07.2009 12:37:12
Согласно P.S. - рекомендовать нечего, поскольку нормальные пути ты отметаешь в корне и судьба твоя незавидна, дальше проблем будет только больше.

--
http://www.podgoretsky.com
Кроик Семён
Дата: 10.07.2009 12:46:58
может поможет (здесь, правда, dBase-база была):

тынц


.....
.....

form.qMain.params.removeAll()
if empty(form.etyPN_Filter.value)
   form.qMain.sql := "SP_GETBATCH"
else
   form.qMain.sql := "EXECUTE SP_GETBATCHBYPN :PARTNUM" // Requires EXECUTE keyword.
   form.qMain.params["PARTNUM"] = form.etyPN_Filter.value
endif
TRY
   form.qMain.active := true
   form.qMain.rowset.first()
CATCH( Exception e )
   if e.message.left(12).toUpperCase() == "SERVER ERROR"
      msgbox(SQLMessage(), "Warning", 48)
   else
      msgbox(e.message, "Warning", 48)
   endif
   return false
ENDTRY


.....
.....

The syntax for this code isn’t too tricky, at least it isn’t with a good example. The only other part to note in this section is how the code is handling potential errors. The default exception class in dBASE tends to truncate the last portion of long error messages. The SQLMessage() function allows us to grab the full message for whatever the last SQLServer error was. I tend to use this kind of code for the global function I use that catches all errors in my dBASE apps.
Кроик Семён
Дата: 10.07.2009 12:52:45
P.S.
sorry

кажись поспешил с постом ....
в справке по Delphi функцию SQLMessage() не нашел (решил проверить, что запостил).
Кроик Семён
Дата: 10.07.2009 12:58:24
P.P.S.

а это обрезается?

  if e is EDBEngineError then Memo1.Lines.Add(EDBEngineError(e).Message);
Руслан Иванофф
Дата: 11.07.2009 01:00:31
Кроик Семён
P.P.S.

а это обрезается?

  if e is EDBEngineError then Memo1.Lines.Add(EDBEngineError(e).Message);


Да!
Руслан Иванофф
Дата: 11.07.2009 01:08:39
Внедрение в процесс в момент, когда на экране выведено сообщение о ошибке, показало, что полный текст сообщения присутствует в памяти в двух экземплярах. При этом несколько экземпляров сообщения в памяти находятся уже в обрезанном виде. Может не так все безнадежно? Возможно в исходниках модулей DBTables и DB можно найти код, в котором ошибка искажается? Знать бы где и как искать!!! Но есть и опасения, что ошибка в самом движке BDE. Тогда все безнадежно.
Дураг
Дата: 11.07.2009 15:05:39
Руслан Иванофф
Внедрение в процесс в момент, когда на экране выведено сообщение о ошибке, показало, что полный текст сообщения присутствует в памяти в двух экземплярах. При этом несколько экземпляров сообщения в памяти находятся уже в обрезанном виде. Может не так все безнадежно? Возможно в исходниках модулей DBTables и DB можно найти код, в котором ошибка искажается? Знать бы где и как искать!!! Но есть и опасения, что ошибка в самом движке BDE. Тогда все безнадежно.


отказаться от BDE совсем никак?
на самом деле это не такая уж сложная проблема!
переводил сам приложение, примерно 200 форм, и ничего ...
подумайте!
Руслан Иванофф
Дата: 13.07.2009 16:14:45
Сложно уйти от BDE, но похоже что придется уходить.