Текущий архив: 2003.10.23;
Скачать: CL | DM;
Вниз
Трехзвенка на Delphi 3 + MS Access + ODBC + BDE Найти похожие ветки
← →
PGrinevich (2003-10-02 11:37) [0]Уважаемые мастера!
Для простоты описания проблемы пример несколько гипотетичен.
На форме расположены:
TDatabase, подлюченный к MS Access через ODBC-драйвер,
TTable, TProvider, TClientDataSet.
При вызове ApllyUpdates после добавлении записей в TClientDataSet
возникает ошибка:
> Invalid field name.
> [Microsoft][Драйвер ODBC Microsoft Access] Инструкция INSERT INTO содержит неизвестное имя поля "CLASS.ID".
> Прверьте, что ...
Очевидно MS Access не понимает синтаксиса CLASS.ID при выполнении операции INSERT,
поле ID в таблице CLASS существует.
Изменение и удаление записей такой ошибки не вызывают.
При использованиии вместо ODBC драйвера Native драйвера BDE таких проблем не возникает, но
возникают другие, ... :( Поэтому хотелось бы услышать совета по решению проблемы связки
BDE->ODBC->Access.
Пробовал то же самое на семерке - все работает, даже с той же BDE, похоже проблема в DBCLIENT.DLL :(
Но все же надеюсь, на помощь.
← →
PGrinevich (2003-10-03 12:00) [1]Поблема разрешилась перекрытием ApplyUpadtes у TProvider.
function TMyProvider.ApplyUpdates(Delta: OleVariant; MaxErrors: Integer;
out ErrorCount: Integer): OleVariant;
var
ds: TClientdataSet;
i: Integer;
qUp: TQuery; // TQuery для выполнения запроса на добавление
sql: String; // текст запроса на добавление записей
fl: TStrings; // список имен полей
tn: String; // имя таблицы
// True - если все записи в Delta на добавление
function _usok: Boolean;
begin
Result := True;
ds.First;
while Result and not ds.EOF do
begin
Result := (ds.UpdateStatus = usInserted);
ds.Next;
end;
end;
// выделить имя таблицы, к которой привязан провайдер
// пустая строка если неудача (несколько таблиц в select)
function _etn: String;
var
s: TStrings;
begin
Result := "";
if DataSet is TTable then
Result := TTable(DataSet).TableName
else
if DataSet is TQuery then
begin
// выделение имен таблиц учавствующих в запросе
s := SQLExtractDependedTables(TQuery(DataSet).SQL.Text);
try
if (s.Count = 1) then
Result := s[0];
finally
s.Free;
end;
end;
end;
// построить список полей
function _bfl: TStrings;
var
i: Integer;
begin
Result := TStringList.Create;
for i := 0 to ds.FieldCount-1 do
Result.AddObject(ds.Fields[i].FieldName, ds.Fields[i]);
end;
begin
ds := TClientdataSet.Create(nil);
try
ds.Data := Delta;
tn := _etn;
// если запрос
if (tn <> "") and _usok then
try
qUp := TQuery.Create(nil);
try
// привязка к базе данных
qUp.SessionName := DataSet.SessionName;
qUp.DatabaseName := DataSet.DatabaseName;
sql := Format("INSERT INTO %s (", [tn]);
// формируем SQL на добавление
fl := _bfl;
try
// поля
for i := 0 to fl.Count-2 do
sql := sql + fl[i] + ",";
sql := sql + fl[fl.Count-1] + ") VALUES (";
// параметры
for i := 0 to fl.Count-2 do
sql := sql + ":" + fl[i] + ",";
sql := sql + ":" + fl[fl.Count-1] + ")";
qUp.SQL.Text := sql;
qUp.Prepare;
// по всем записям
ds.First;
while not ds.EOF do
begin
// заполняем параметры
for i := 0 to fl.Count-1 do
qUp.ParamByName(fl[i]).AssignField(TField(fl.Objects[i]));
// добавляем запись
qUp.ExecSQL;
// перход к следующей записи
ds.Next;
end;
// все хорошо - очищаем Delta
Delta := null;
finally
fl.Free;
end;
finally
qUp.Free;
end;
except
// ошибка при добавлении записи ???
end;
if Not VarIsNull(Delta) then
Result := inherited ApplyUpdates(Delta, maxErrors, ErrorCount)
else
Result := null;
finally
ds.Free;
end;
end;
Страницы: 1 вся ветка
Текущий архив: 2003.10.23;
Скачать: CL | DM;
Память: 0.47 MB
Время: 0.016 c