Делаем ApplyUpdates. Если при insert(update) произошла ошибка (поле null, сработал check, etc.), то BDE всегда говорит "General SQL Error" вместо нормального сообщения об ошибке :-( Без CU все нормально, разумеется. Как бороть этот баг?
Nomadicсоветует:
Использyй нормальнyю трансляцию ошибок в Application.OnException. Вpоде это.
procedure DBExceptionTranslate(E: EDBEngineError);
functionOriginalMessage: String;
var
I: Integer;
DBErr: TDBError;
S: String;
begin
Result := '';
forI := 0 toE.ErrorCount - 1 do begin
DBErr := E.Errors[I];
caseDBErr.NativeError of
-836: { Intebase exception }
begin
S := DBErr.Message;
Result := #13#10 + Copy(S, Pos(#10, S) + 1, Length(S));
Exit;
end;
end;
S := Trim(DBErr.Message);
ifS <> '' thenResult := Result + #13#10 + S;
end;
end;
begin
caseE.Errors[0].ErrorCode of
$2204:
E.Message := LoadStr(SKeyDeleted);
$271E,$2734:
E.Message := LoadStr(SInvalidUserName);
$2815:
E.Message := LoadStr(SDeadlock);
$2601:
E.Message := LoadStr(SKeyViol);
$2604:
E.Message := LoadStr(SFKViolation) + OriginalMessage;
else begin
E.Message := Format(LoadStr(SErrorCodeFmt), [E.Errors[0].ErrorCode]) + OriginalMessage;
end;
end;
end;
Ошибка создания дескриптора курсора
Вы должны использовать ExecSql вместо Open. К примеру, если имя вашего запроса UpdateStudent, то при необходимости обновления STUDENT.DB вы должны использовать следующий код:
Begin
…
UpdateStudent.ExecSql;
…
End;
Ваш запрос является Passtrough-запросом, который не может возвратить установленный результат, так что это не может быть открыто, а должно быть 'ВЫПОЛНЕНО'.
При разрушении обьектов, порожденных от TDataSet (TTable, TQuery), не отрабатывает событие OnBeforeClose. Что делать?
Nomadicотвечает:
Недоработка в VCL.
Сейчас вышел из ситуации так: в TForm.OnClose, т.е. пока ещё все компоненты формы живы, делаю CloseDatabases(Self).
При обращении к memo-полю из BDE возникает ошибка 'Memo too large'. Как лечить?
Nomadicотвечает:
В BDE есть крутая ошибка, достаточно известная всем, кроме Borland'a. Поскольку они ее еще с 1й Delphi не исправили. Этот баг проявляется как Access Violation в программе при обращении к таблице IB, которая содержит более одного поля типа VARCHAR (или CHAR) размером>255. Причем, первое поле меньшего, а второе большего размера. Если поменять местами поля или сделать их одного размера, то все нормально.
Эффект имеет место только с IB, вроде.
Нарушение уникальности записи
try
tMyTable.Post;
except
on E : EDBEngineError do ifE.Message = 'Key violation' then begin
MessageDlgC('Дублирование записи не допускается.' mtError, [mbOk], 0);
// Я не уверен в том, что это нужно делать:
tMyTable.Cancel;
end
else Raise;
end;
Хорошим примером может служить проект DBERRORS.DPR, расположенный в каталоге Delphi 2 Demos. Выглядит это примерно так:
Создайте функцию типа этой:
functionDBError(DataSet: TDataSet; E: EDatabaseError; varAction: TDataAction);
consteKeyViol = 9729;
variDBIError: Integer;
begin
if(E isEDBEngineError) then begin
iDBIError := (E asEDBEngineError).Errors[0].Errorcode;
caseiDBIError of
eKeyViol:
begin
MessageDlg('Нарушение уникальности записи ', mtWarning, [mbOK], 0);
Abort;
end;
end;
Затем для каждой таблицы вашего приложения создайте следующий обработчик события:
procedureTMainForm.Table1EditError(DataSet: TDataSet; E: EDatabaseError; varAction: TDataAction);
begin
DBError(Table1, E, Action);
end;
Таким образом вы можете перехватить множество ошибок. Смотрите примеры от Borland, там много чего есть полезного.
При выполнении некоторых живых запросов, возвращающих единственную запись, BDE ругается 'multiple records found, but only one was expected'. Как лечить?
Nomadicотвечает:
Запросы вида SELECT c, b, a, q FROM T WHERE b = :b, где ключ c, но BDE посчитала ключом a. Интересный запрос, да? Такое впечатление, что, поскольку ключом в исходной таблице являлась третья колонка, то Дельфы посчитали ключом третью колонку.
Читать дальше