Перехват ошибок SQL на Delphi в ADOConnection
Перехват ошибок SQL на Delphi при работе с компонентом ADO
Механизм, как «запретить — разрешить» выводить сообщение об ошибке подключения программы на Delphi через SQL через компонент TADOConnection.
Типичная обработка ошибки заключается в том, чтобы обрамить блоки кода в конструкции try..except или try..finally. Однако, многие попросту не делают этого, так как им недосуг или обработка исключений оставляется «на потом».
Чтобы не выводить сообщения об ошибке можно написать такой код, используя конструкцию «try-finally»:
procedure TAnswerList.Update(ADO : TADOQuery); begin with ADO do begin if Active then Close; SQL.Text:=concat('UPDATE ANSWER_LIST SET ', 'NAME = "', self.Name, ', ', 'NOMER_ID = "', IntToStr(self.Nomer), ', ', 'CREDITOR_ID = "', IntToStr(self.CreditorId), ' ', 'WHERE ID = ' + IntToStr(self.id)); try ExecSQL; finally end; end; end;
Чтобы грамотно вывести сообщение об ошибке можно использовать другую конструкцию:
procedure TAnswerList.Update(ADO : TADOQuery); begin with ADO do begin if Active then Close; SQL.Text:=concat('UPDATE ANSWER_LIST SET ', 'NAME = "', self.Name, ', ', 'NOMER_ID = "', IntToStr(self.Nomer), ', ', 'CREDITOR_ID = "', IntToStr(self.CreditorId), ' ', 'WHERE ID = ' + IntToStr(self.id)); try ExecSQL; except On E:Exception Do begin ShowMessage(concat('Update answer list failure. ',e.Message,#13#10,SQL.Text)); Exit; end; end; end;
Как вариант, Вы можете использовать свойство Application.OnException, которое является глобальным обработчиком событий приложения.
Для этого предлагается оформить обработку исключений в отдельный компонент.
unit sExceptionsCatcher; {***} interface {***} uses Classes, SysUtils, JPEG; type TsExceptionsCatcher = class(TComponent) private FEnabled: boolean; FGenerateScreenshot: boolean; FJPEGScreenshot: boolean; FJpegQuality: TJPEGQualityRange; FCollectInfo: boolean; Fn: TFilename; procedure SetEnabled(const Value: boolean); { Private declarations } protected { Protected declarations } procedure EnableCatcher; procedure DisableCatcher; public { Public declarations } constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure Catcher(Sender: TObject; E: Exception); published { Published declarations } property Enabled: boolean read FEnabled write SetEnabled default False; end; procedure Register; {***} implementation {***} uses Windows, Forms, Dialogs, Graphics; procedure Register; begin RegisterComponents('Catch Exceptions', [TsExceptionsCatcher]); end; { TsExceptionsCatcher } constructor TsExceptionsCatcher.Create(AOwner: TComponent); begin inherited; end; destructor TsExceptionsCatcher.Destroy; begin DisableCatcher; inherited; end; procedure TsExceptionsCatcher.SetEnabled(const Value: boolean); begin FEnabled := Value; if Enabled then EnableCatcher else DisableCatcher; end; procedure TsExceptionsCatcher.DisableCatcher; begin Application.OnException := nil; end; procedure TsExceptionsCatcher.EnableCatcher; begin Application.OnException := Catcher; end; procedure TsExceptionsCatcher.Catcher(Sender: TObject; E: Exception); begin {TODO: Write some exception handling code} end; end.
Реализация функций
// скриншот активного окна procedure TsExceptionsCatcher.DoGenerateScreenshot; var bmp: TBitmap; jpg: TJPEGImage; begin bmp := Screen.ActiveForm.GetFormImage; begin jpg := TJPEGImage.Create; jpg.CompressionQuality := 100; jpg.Assign(bmp); jpg.SaveToFile(fn+'.jpg'); FreeAndNil(jpg); end; FreeAndNil(bmp); end;
// отчет, в котором будут указаны имя компьютера и имя текущего пользователя function TsExceptionsCatcher.CollectUserName: string; var uname: pchar; unsiz: cardinal; begin uname := StrAlloc(255); unsiz := 254; GetUserName(uname,unsiz); if (unsiz > 0) then Result := string(uname) else Result := 'n/a'; StrDispose(uname); end; function TsExceptionsCatcher.CollectComputerName: string; var cname: pchar; cnsiz: cardinal; begin cname := StrAlloc(MAX_COMPUTERNAME_LENGTH + 1); cnsiz := MAX_COMPUTERNAME_LENGTH + 1; GetComputerName(cname,cnsiz); if (cnsiz > 0) then Result := string(cname) else Result := 'n/a'; StrDispose(cname); end;
// Процедура создает объект класса TStringList, наполняет его информацией, которую надо записать и сохраняет в файл, // с именем, аналогичном имени файла со скриншотом procedure TsExceptionsCatcher.DoCollectInfo(E: Exception); var sl: TStringList; begin sl := tstringlist.Create; sl.add('--- This report is created by automated '+ 'reporting system.'); sl.add('Computer name is: ['+ComputerName+']'); sl.add('User name is: ['+UserName+']'); sl.add('--- End of report ----------------------'+ '-----------------'); sl.SaveToFile(Fn+'.txt'); end;
Дата публикации: 2015-05-12 10:36:28
← →
Ануфрий
(2007-08-03 19:30)
[0]
С некоторых пор Дельфи стал показывать сообщения об ошибках (исключениях), которые пойманы через try.
Т.е. код до этого
try
I := деление на ноль;
finally
end
Приводил к тому, что в режиме отладки дельфи сообщал об ошибке, и после нажатия F9 программа дальше работала. Без дельфи прога вообще ничего не выдавала.
Теперь показывается сообщение дельфи и после F9 вылетает MessageBox.
А если запускать без дельфи, то просто вылетает MessageBox (типа деление на ноль).
Раньше все было нормально, не пойму что случилось и как это убрать.
← →
Dib@zol ©
(2007-08-03 19:32)
[1]
А может просто не делить на ноль??? Или это просто такой пример?
← →
Ануфрий
(2007-08-03 19:35)
[2]
Это пример.
← →
Anatoly Podgoretsky ©
(2007-08-03 19:39)
[3]
> Ануфрий (03.08.2007 19:35:02) [2]
В этом примере не делить на ноль.
← →
Ануфрий
(2007-08-03 19:42)
[4]
Ну тогда другой пример.
var
HTTP: TIdHTTP;
Str: string;
begin
HTTP := TIdHTTP.Create(nil);
try
Str := HTTP.Get("http://my_domain.com");
finally
HTTP.Free;
end;
end;
При запуске вызывается исключение (сайт не найден). Мне нужно чтобы на экран не выдавалось сообщение с текстом исключения.
← →
Dib@zol ©
(2007-08-03 19:43)
[5]
var
HTTP: TIdHTTP;
Str: string;
begin
HTTP := TIdHTTP.Create(nil);
try
Str := HTTP.Get(«http://my_domain.com»);
finally
HTTP.Free;
end;
end;
try..finally заменяй на try..except.
← →
Anatoly Podgoretsky ©
(2007-08-03 19:45)
[6]
> Ануфрий (03.08.2007 19:42:04) [4]
Чтобы на экран не выдавалось сообщение, исключение надо обработать самому, это блок try except end
← →
Anatoly Podgoretsky ©
(2007-08-03 19:46)
[7]
> Dib@zol (03.08.2007 19:43:05) [5]
try..finally убирать нельзя, это будет уже другая ошибка дизайна, например утечка как минимум
← →
Ануфрий
(2007-08-03 19:49)
[8]
Dib@zol
Спасибо, работает. Хотя я всегда думал, что finally также «поглощает» ошибки, как except, только в отличие от последнего вызывается всегда, даже если ошибок нет. И вроде бы так и работало… Может просто не разу ошибок не попадалось внутри try finally end;
← →
Ануфрий
(2007-08-03 19:52)
[9]
Anatoly Podgoretsky
Так нужно делать вложенные try что-ли?var
HTTP: TIdHTTP;
Str: string;
begin
HTTP := TIdHTTP.Create(nil);
try
try
Str := HTTP.Get("http://my_domain.com");
except
end;
finally
HTTP.Free;
end;
end;
Тогда наверное проще заменить наvar
HTTP: TIdHTTP;
Str: string;
begin
HTTP := TIdHTTP.Create(nil);
try
Str := HTTP.Get("http://my_domain.com");
except
end;
HTTP.Free;
end;
?
← →
Ануфрий
(2007-08-03 19:56)
[10]
Посмотрел старый код. Раньше у меня тоже было try finally end. И никогда ошибки на экран не выдавались.
← →
Zagaevskiy ©
(2007-08-03 19:57)
[11]
Может ошибок там не было?
← →
Инс ©
(2007-08-03 19:57)
[12]
> Тогда наверное проще заменить на
В данном конкретном случае можно, но вообще лучше 1-й вариант.
← →
{RASkov} ©
(2007-08-03 19:58)
[13]
> [9] Ануфрий (03.08.07 19:52)
> Тогда наверное проще заменить на
> var
> HTTP: TIdHTTP;
> Str: string;
> begin
> HTTP := TIdHTTP.Create(nil);
> try
> Str := HTTP.Get(«http://my_domain.com»);
> except
> end;
> HTTP.Free;
> end;
> ?
Не верно!
var
HTTP: TIdHTTP;
Str: string;
begin
HTTP := TIdHTTP.Create(nil);
try
try
Str := HTTP.Get("http://my_domain.com");
except
ShowMessage("Произошла ошибка такая-то");
end;
finally
HTTP.Free;
end;
end;
← →
Инс ©
(2007-08-03 19:58)
[14]
> [10] Ануфрий (03.08.07 19:56)
Почитай Рихтера, у него отлично механизм исключений расписан.
← →
Anatoly Podgoretsky ©
(2007-08-03 20:01)
[15]
> Ануфрий (03.08.2007 19:52:09) [9]
Для данного кода можно написать с одним блоком, но обычно код сложнее и
except
end
Лучше заменить на
except
что то полезное.
end
← →
Anatoly Podgoretsky ©
(2007-08-03 20:08)
[16]
> Anatoly Podgoretsky (03.08.2007 20:01:15) [15]
Хотя бы на
except
on E.Exception do begin
// variable := E.Message
//или
// LOG(llCriticalLevel, «Ошибка HTTP.Get(http://my_domain.com) = » + E.Message);
end;
end
Это позволит как минимум поставить точку останова для отладки.
← →
Ануфрий
(2007-08-03 20:10)
[17]
Все, спасибо всем, просто заработался.
function GetBody(const URL: string): string;
var
HTTP: TIdHTTP;
Str: string;
begin
Result := "";
HTTP := TIdHTTP.Create(nil);
try
Result := HTTP.Get("http://my_domain.com");
finally
HTTP.Free;
end;
end;
а далее вызов так
try
S := GetBody("http://domain.com");
except
S := "";
end;
потому ошибки не было. А когда я начал разбираться с GetBody, видел только finally и это меня смутило, почему вдруг стали ошибки появляться.
← →
Anatoly Podgoretsky ©
(2007-08-03 20:23)
[18]
> Ануфрий (03.08.2007 20:10:17) [17]
Вот это грамотный код.
At the moment I have a Delphi form running and upon losing connection to its Database/loss of network, it re-establishes and carries on.
The service is on a timer and each minute, it pops up with message box saying failure to connected to db on network [ip address]. This is at the start of the timer, a stored proc is ran.
I have all errors writing to a log file on the service local machine, is there a way I can suppress the message box appearing as I don’t need it to appear all the time? by message box it is a windows exception box not a showMessageBox(). It automatically pops up when the exception hits but it will continuously hit whilst the machine boots up and re-establishes connection to the network.
The code I have is as follows
(*Call db Procedure*)
try
db.SQL.Clear;
db.SQL.Add('call dbProc();');
db.ExecSQL;
except
On E : Exception Do
begin
If E.ClassName = 'EIBInterBaseError' Then
begin
WriteToLog('Network Error : An error has occured whilst trying to communicate with the db outside the'
+ ' loop to catch up , please see user guide V.1.0.2.145',2);
reconnectdb;
end
else if E.ClassName = 'EADOError' then
begin
WriteToLog('Network Error : An error has occured whilst trying to communicate with the db outside the'
+ ' loop to catch up , please see user guide V.1.0.2.145',2);
reconnectDB;
end;
end;
end;
476 / 444 / 34 Регистрация: 20.11.2009 Сообщений: 1,293 |
|
1 |
|
Отключить сообщение об исключении08.07.2010, 13:52. Показов 4091. Ответов 7
Если запускать приложение прямо в делфи, то когда происходит исключение, делфи благим матом орет об этом, даже если исключение отловлено. Это надоедает. Можно отключить? (Если просто запускать экзешник — все нормально) Добавлено через 15 минут
0 |
КотЪ 219 / 219 / 60 Регистрация: 26.05.2009 Сообщений: 688 |
|
08.07.2010, 14:25 |
2 |
Если исключение возникает — значит ваша программа работает не так, как нужно или с ошибками.
0 |
Хохол 476 / 444 / 34 Регистрация: 20.11.2009 Сообщений: 1,293 |
||||
08.07.2010, 14:37 [ТС] |
3 |
|||
Я проверяю, введено ли в текстовое поле число — чето типа
Конкретно в данном случае исключение не означает неправильной работы программы. И уж тем более мне не нужно сообщать об отловленном исключении.
0 |
VampireKB 36 / 35 / 3 Регистрация: 12.06.2009 Сообщений: 211 |
||||
08.07.2010, 21:33 |
4 |
|||
проблема знакомая,но я нашел более чёткое решение )
1 |
476 / 444 / 34 Регистрация: 20.11.2009 Сообщений: 1,293 |
|
08.07.2010, 21:55 [ТС] |
5 |
О, спасибо, VampireKB, давно мне такой штуки не хватало
0 |
36 / 35 / 3 Регистрация: 12.06.2009 Сообщений: 211 |
|
08.07.2010, 22:06 |
6 |
я в своё время просто тоже с такой проблемой столкнулся..и было тупо влом нажимать на ОК после каждого try except-а
0 |
Хохол 476 / 444 / 34 Регистрация: 20.11.2009 Сообщений: 1,293 |
||||
08.07.2010, 22:10 [ТС] |
7 |
|||
Советую писать
может это ваш стиль, конечно, но некоторые удивляются, что так можно…
0 |
36 / 35 / 3 Регистрация: 12.06.2009 Сообщений: 211 |
|
09.07.2010, 00:08 |
8 |
Если учесть,что я самоучка ,и многих вещей не знаю,то простительно,надеюсь )
0 |
- Главная
- Исходники Delphi
- Справочники Delphi
- Книги Delphi
- Основы Delphi
- библиотека Delphi исходников
- Форум
- Блоги
Последние записи
- PostgreSQL — чтение файла
- Обязательное прикрепление изображений
- Игра «Крестики-Нолики» на чистом HTML (без скриптов)
- Динамическое создание массива TScrollBar
- Как разместить форму в панель задач?
- CMD скрипт, запустить из memo
- Как проверить работу сессий на PHP
- Как узнать дату окончания сертификата
- Как передать значение во внешний JS-скрипт?
- Определить количество знаков после запятой
- .NET
- ASP.NET
- assembler
- Basic
- c/c++
- CMS
- Delphi
- Gamedev — cоздание игр
- HTML
- iPhone
- Java
- JavaScript
- Lazarus, Free Pascal
- Linux
- Pascal
- Perl
- Photoshop
- php
- Python
- QT
- Ruby
- SEO
- sql
- VBA
- Win Api
- Windows
- XML и XSLT
- Администрирование ОС
- Апгрейды
- Архив
- Безопасность
- Блоги
- Веб-аналитика
- Железо
- Журнал
- Заметки
- Имейдж
- Интервью
- Исходники
- Микроконтроллеры
- Новости
- Общалка
- Операционные системы
- Пост-обзор
- Профлитература
- Рассылка
- Реклама
- си шарп
- Советы
- Софт
- Статьи
- Топик-обзор
- Файлы
Интенсив по Python: Работа с API и фреймворками 24-26 ИЮНЯ 2022. Знаете Python, но хотите расширить свои навыки?
Slurm подготовили для вас особенный продукт! Оставить заявку по ссылке — https://slurm.club/3MeqNEk
Online-курс Java с оплатой после трудоустройства. Каждый выпускник получает предложение о работе
И зарплату на 30% выше ожидаемой, подробнее на сайте академии, ссылка — ttps://clck.ru/fCrQw
Купить рекламу на сайте за 1000 руб
пишите сюда — alarforum@yandex.ru
Да и по любым другим вопросам пишите на почту
пеллетные котлы
Пеллетный котел Emtas
Наши форумы по программированию:
- Форум Web программирование (веб)
-
- Форум Python (питон)
- Форум PHP (пхп)
- Форум Perl (перл)
- Форум Ruby (руби)
- Форум JavaScript (яваскрипт)
- Форум Ajax (аякс)
- Форум SQL (эскюэл)
- Форум HTML (хтмл)
- Форум CSS (сиэсэс)
- Форум XML (иксмл)
- Форум JSON (джсон)
- Delphi форумы
-
- Форум Pascal (паскаль)
- Форум Delphi (делфи)
- Форумы C (Си)
-
- Форум C++ (си плюс плюс)
-
- Форум C++ Builder (си билдер)
- Форум Visual C++ (визуал си)
- Форум Qt (Кью Тэ)
- Форум C# (си шарп)
- Форум .NET Frameworks (точка нет фреймворки)
-
- Форум .NET (точка нет)
- Форум ASP.NET (асп нет)
- Форум Windows Forms (виндовс формс)
- Форум базы данных ADO.NET (адо нет)
- Форум .NET Framework WPF, UWP, WinRT, XAML ()
- Форум Java (джава)
-
- Форум Java Android (джава андроид)
- Форум Java web (джава веб)
- Форум Kotlin (котлин)
- Форум низкоуровневое программирование
-
- Форум Assembler (ассемблер)
- Форум WinApi (вин апи)
- Форум VBA (вба)
-
- Форум Excel (эксель)
- Форум Word (ворд)
- Форум Access (аксесс)
- Форум OpenGL
- Форум DirectX
- Форум CAD проектирование
- Форум по операционным системам
-
- Форум по администрированию ОС
- Форум по администрированию серверов и VDS
- Форум Windows
- Форум Ubuntu
- Форум Android
- Форум Software (Софт)
- Форум Hardware (Компьютерное железо)