Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > BOF or EOF = True на sp.Parameters.Refresh


Автор: kami 26.11.2013, 13:35
Добрый день, уважаемые!
Столкнулся с непонятной мне проблемой в виде "EOLEException - BOF или EOF имеет значение True, либо текущая запись удалена."
Но возникает оно на Parameters.Refresh, что как бы вообще не.

Код

sp := TADOStoredProc.Create(nil);
try
  sp.Connection:=ADOConn; // заранее созданное соединение.
  SomeList1.ReadFromDB(sp);
  SomeList2.ReadFromDB(sp);
finally
  sp.Free;
end;

Реализация ReadFromDB почти идентичная:
Код

procedure TSomeList1.ReadFromDB(sp: TADOStoredProc);
begin
  sp.ProcedureName := spSomeProcName1;
  sp.Parameters.Refresh;
  sp.Parameters.ParamByName('ParamName').Value := Value; //  Единственное отличие. У второй процедуры параметра нет.
  // соответственно - нет и этой строки.
  sp.Open;
  try
    ReadFromDS(sp); // здесь - чтение, пока не sp.eof
  finally
    sp.Close;
  end;
end;

procedure TSomeList2.ReadFromDB(sp: TADOStoredProc);
begin
  sp.ProcedureName := spSomeProcName2;
  sp.Parameters.Refresh; // здесь - исключение.
 ...
end;

Callstack указывает на:
  ADODB.RefreshFromADO
  ADODB.TParameters.InternalRefresh
  ADODB.TParameters.Refresh

Меняем местами List1 и List2 - проблема исчезает, но это половинчатое решение - списков может быть несколько, часть с параметрами, часть без.
Почему так и что можно сделать?

Автор: Frees 29.11.2013, 11:28
Код

procedure TSomeList1.ReadFromDB(sp: TADOStoredProc);
begin
  sp.Close;//может в нем проблема
  sp.ProcedureName := spSomeProcName1;

Автор: kami 29.11.2013, 14:01
Цитата(Frees @  29.11.2013,  11:28 Найти цитируемый пост)
sp.Close;//может в нем проблема

Увы - нет. Пробовал и так, но sp гарантированно закрыта.
Принудительное добавление sp.Close в оба (и по отдельности) метода ReadFromDB результата не дает, ошибка та же...

P.S. изначально забыл сказать - используется D2010, Win7 со всеми обновлениями.

Автор: Frees 3.12.2013, 13:06

Цитата(kami @  29.11.2013,  17:01 Найти цитируемый пост)
P.S. изначально забыл сказать - используется D2010, Win7 со всеми обновлениями.

если есть демо проект с этой ошибкой, могу проверить на XE3

Автор: kami 3.12.2013, 21:13
Цитата(Frees @  3.12.2013,  13:06 Найти цитируемый пост)
если есть демо проект с этой ошибкой, могу проверить на XE3

Думаю, что дело не в Delphi... хотя...
Минимальная конфигурация (другой, к сожалению, нет), на которой воспроизводится это хозяйство:
MySQL v5.6 + ODBC драйвер (ох, не помню версию, но вроде последняя - 5.2.6). В параметрах ODBC -подключения всё по умолчанию, кроме: Enable automatic reconnect и Allow multiple statements= True.

Скрипт для БД:
Код

delimiter $$
CREATE DATABASE `test`$$

CREATE TABLE `testtable` (
  `ttID` int(11) NOT NULL AUTO_INCREMENT,
  `ttValue` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`ttID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$

CREATE PROCEDURE `spSomeProc1`(Param INT)
BEGIN
  SELECT `ttID`, `ttValue` FROM `test`.`testtable` WHERE `ttID` = Param;
END$$

CREATE PROCEDURE `spSomeProc2`()
BEGIN
  SELECT `ttID`, `ttValue` FROM `test`.`testtable`;
END$$
DELIMITER ;


Код приложения уместился в один обработчик события:
Код

procedure TForm1.btn1Click(Sender: TObject);
var
  sp: TADOStoredProc;
  conn: TADOConnection;
begin
  conn:=TADOConnection.Create(nil);
  try
    conn.ConnectionString:=ADODB.PromptDataSource(0, '');  // у меня получилось 'Provider=MSDASQL.1;Persist Security Info=False;Data Source=Test'

    sp:=TADOStoredProc.Create(nil);
    try
      sp.Connection:=conn;

      sp.ProcedureName:='spSomeProc1';
      sp.Parameters.Refresh;
      sp.Parameters.ParamByName('Param').Value:=1;
      sp.Open;
      try
      finally
        sp.Close;
      end;

      sp.ProcedureName:='spSomeProc2';
      sp.Parameters.Refresh;
      sp.Open;
      try
      finally
        sp.Close;
      end;
    finally
      sp.Free;
    end;
  finally
    conn.Free;
  end;
end;

Автор: Frees 4.12.2013, 06:38
MySQL у меня нет, пробовал на Firebird через ODBC, на Delphi XE3.

Conn - создавал в дизайне.
в твоем коде не хватает  conn.Connected := True;

Ошибок не видел.

Автор: kami 4.12.2013, 08:42
Цитата(Frees @  4.12.2013,  06:38 Найти цитируемый пост)
в твоем коде не хватает  conn.Connected := True;

Оно автоматом выставится при первом sp.Open.

Цитата(Frees @  4.12.2013,  06:38 Найти цитируемый пост)
Ошибок не видел.

Тогда - одно из двух. Либо мускул и его ODBC, либо Delphi 2010... (надеюсь, третье - кривые руки можно исключить). С Delphi и мускула я не слезу, так что... оставим всё как есть, благо это исключение вылезает только при отладке, даже не влияя на дальнейшее выполнение кода, правда - что происходит с самими параметрами при этом - не выяснял...

Автор: Frees 4.12.2013, 17:42
Цитата(kami @  4.12.2013,  11:42 Найти цитируемый пост)
Оно автоматом выставится при первом sp.Open.

Было исключение на Refresh, о том что нет коннекта.

Автор: kami 4.12.2013, 21:48
Цитата(Frees @  4.12.2013,  17:42 Найти цитируемый пост)
Было исключение на Refresh, о том что нет коннекта.

А вот это странно. Ибо (по крайней мере в D2010) в TParameters.Refresh первым делом вызывается Command.SetConnectionFlag(cfParameters, True)и в нем железобетонно (при неактивном соединении) OpenConnection.

Добавлено через 2 минуты и 27 секунд
Да это легко проверить и в дизайнтайм - при любой манипуляции с параметрами, списком полей, при попытке выбрать из списка имя sp или выставить sp.Active - автоматом активируется ADOConnection.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)