Рейтинговые книги
Читем онлайн Советы по Delphi. Версия 1.4.3 от 1.1.2001 - Валентин Озеров

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 31 32 33 34 35 36 37 38 39 ... 123

begin

 theStrList := TStringList.Create;

 {Используем GetAliasParams для получения псевдонимов и ассоциированных с ними путей}

 Session.GetAliasParams(<Здесь псевдоним из выпадающего списка>,theStrList);

 {Удаляем первые шесть символов, которые всегда равны «PATH="}

 GPath := copy(theStrList[0],6,length(theStrList[0]))

 theStrList.Free;

Ошибки 

Ошибка BDE32 $2104

Delphi 2 

Пример, приведенный для функции dbiGetDatabaseDesc в файле BDE32.HLP, неверен. Такой же пример содержится в файле TI3100.ASC. Я пробовал это на 3 разных компьютерах. Я использую среду Delphi. Ошибка, которую я получаю при попытке использования функции, выглядит следующим образом:

EDBEngineError с сообщением 'Возникла ошибка при попытке инициализации Borland Database Engine (ошибка $2104).'

При вызове любой из функций BDE, если вы не пользуетесь компонентами для работы с базами данных, вам необходимо инициализировать BDE вызовом dbiInit(nil).

Pat Ritchey 

Проблема BDE при использовании "неживого" TQuery

У меня была та же проблема, и я нашел единственное решение как ее обойти. Я подозреваю, что причина кроется в том, что Query1.Refresh ничего не делает, если установлен режим readonly, т.е. не ожидается никаких изменений. Один способ у меня прошел успешно (в предположении, что мы имеем один вход): я использовал 3 TQuerie, две сетки и форму обновления. Это способ, когда я могу установить requestlive в истину. Вы не должны допускать, чтобы пользователь мог сам редактировать табличную сетку (если это то, что вы хотите). 

Ошибка ApplyApdates

Делаем ApplyUpdates. Если при insert(update) произошла ошибка (поле null, сработал check, etc.), то BDE всегда говорит "General SQL Error" вместо нормального сообщения об ошибке :-( Без CU все нормально, разумеется. Как бороть этот баг?

Nomadic советует:

Использyй нормальнyю трансляцию ошибок в Application.OnException. Вpоде это.

procedure DBExceptionTranslate(E: EDBEngineError);

function OriginalMessage: String;

var

 I: Integer;

 DBErr: TDBError;

 S: String;

begin

 Result := '';

 for I := 0 to E.ErrorCount - 1 do begin

  DBErr := E.Errors[I];

  case DBErr.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);

 if S <> '' then Result := Result + #13#10 + S;

end;

end;

begin

 case E.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

Ошибка создания дескриптора курсора

Delphi 1 

Вы должны использовать 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, вроде.

Нарушение уникальности записи

Delphi 1

try

 tMyTable.Post;

except

 on E : EDBEngineError do if E.Message = 'Key violation' then begin

  MessageDlgC('Дублирование записи не допускается.' mtError, [mbOk], 0);

  // Я не уверен в том, что это нужно делать:

  tMyTable.Cancel;

 end

 else Raise;

end;

Хорошим примером может служить проект DBERRORS.DPR, расположенный в каталоге Delphi 2 Demos. Выглядит это примерно так:

Создайте функцию типа этой:

function DBError(DataSet: TDataSet; E: EDatabaseError; var Action: TDataAction);

const eKeyViol = 9729;

var iDBIError: Integer;

begin

 if (E is EDBEngineError) then begin

  iDBIError := (E as EDBEngineError).Errors[0].Errorcode;

  case iDBIError of

  eKeyViol:

   begin

    MessageDlg('Нарушение уникальности записи ', mtWarning, [mbOK], 0);

    Abort;

   end;

  end;

Затем для каждой таблицы вашего приложения создайте следующий обработчик события:

procedure TMainForm.Table1EditError(DataSet: TDataSet; E: EDatabaseError; var Action: 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. Интересный запрос, да? Такое впечатление, что, поскольку ключом в исходной таблице являлась третья колонка, то Дельфы посчитали ключом третью колонку.

Перестановкой SELECT a, b, c, q… все исправилось. Я решил теперь использовать в таких (live) запросах только SELECT *.

Как поймать свой RAISEERROR в Delphi?

Nomadic отвечает:

procedure TFDMUtils.GeneralError( DataSet: TDataSet; E: EDatabaseError; var Action: TDataAction);

var

 i: Word;

 ExtInfo : String;

begin

 ExtInfo := '';

 if (E is EDBEngineError) then begin

  if (EDBEngineError(E).Errors[0].NativeError = 0) then begin // Local Error

   if EDBEngineError(E).Errors[0].Errorcode = 9732 then

    ExtInfo := DataSet.FieldByName(trim(copy(E.Message, 29, 20))).DisplayLabel;

   .......................................

  end

  else begin // Remote SQL Server error

   ExtInfo := ExtractFieldLabels(DataSet, E.Message);

   case EDBEngineError( E ).Errors[0].NativeError of

   233, 515:

    Alert('Ошибка', 'Hе все поля заполнены ! ' + ExtInfo);

   547:

    if (StrPos(PChar(E.Message), PChar('DELETE')) <> nil) then

     Alert('Ошибка пpи удалении', 'Имеются подчиненные записи, удаление (изменение) невозможно! ' + ExtInfo)

    else if (StrPos(PChar(E.Message), PChar('INSERT')) <> nil) then

     Alert('Ошибка пpи вставке', 'Отсутствует запись в МАСТЕР-таблице!' + ExtInfo)

    else if (StrPos(PChar(E.Message), PChar('UPDATE')) <> nil) then

     Alert('Ошибка пpи обновлении', 'Отсутствует запись в МАСТЕР-таблице! ' + ExtInfo);

   2601:

    Alert('Ошибка', 'Такая запись уже есть!');

   else

    Alert('Ошибка', 'Hеизвестная ошибка, код – ' + inttostr(EDBEngineError(E).Errors[0].NativeError) + ExtInfo);

   end;

  end;

 end;

end;

Этот код был заточен под MSSQL, но не нужно пытаться его использовать, а лучше по этому пpимеpу написать свою процедуру.

Как добиться верной работы фильтра на запросах и на неиндексированных таблицах?

Nomadic отвечает:

(Т.е. при работе программы наблюдалась следующая картина: в результате очередной фильтрации оставалось видно 4 записи из восьми. Добавляем букву к фильтру, остается, допустим, две. Убираем букву, которую только что добавили, в гриде все равно видно только две записи)

1 ... 31 32 33 34 35 36 37 38 39 ... 123
На этой странице вы можете бесплатно читать книгу Советы по Delphi. Версия 1.4.3 от 1.1.2001 - Валентин Озеров бесплатно.

Оставить комментарий