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


Автор: Avers 15.9.2010, 15:28
Работаю с MS SQL 2005. Компоненты ADO
В приложении должно произойти следующее (код скажет больше, чем я словами): 
Код

const
  CSQLString = 'DDELETE FROM Table1 WHERE (LOWER([Name]) = LOWER(:@Name))'

  with ADOQuery do
    begin
      if Active then
        Close;
      SQL.Clear;
      SQL.Add(CSQLString);
      Parameters.Refresh;
      Parameters.ParamByName('@Name').Value := ANameParam;
      ExecSQL;
    end;

Но на деле не создается, и как следствие не находится, параметр @Name.
Подскажите в чем может быть проблема. Собственных мыслей нет :( ибо подобный код использую уже далеко не впервые. 
В других случаях (чаще это 'EXEC [dbo].[sp_StoredProcedure] :@ParamName' - все работает. 

Автор: pseud 15.9.2010, 15:59
Код

  with ADOQuery do
    begin
      if Active then
        Close;
      SQL.Clear;
      SQL.Add(CSQLString);
      Parameters.Clear;
      Parameters.ParseSQL(SQL.Text, True);
      Parameters.ParamByName('@Name').Value := ANameParam;
      ExecSQL;
    end;

Автор: Avers 15.9.2010, 16:09
Спасибо, помогло. ParseSQL до этого пробовал, но... неверно это делал 

Автор: pseud 15.9.2010, 16:28
Код

Parameters.Clear;

можно убрать, т.к. ParseSQL с установленным Create = True сам делает Clear

Добавлено через 1 минуту и 8 секунд
Avers, и возможно есть другой метод, я то ADO не пользуюсь.

Автор: Avers 15.9.2010, 22:00
Вопрос, конечно решен. Но обнаружилась интересная вещь.
Постарался привести все использование ADO в проекте к однообразию. Т.е.
Код

      Parameters.ParseSQL(SQL.Text, True);
      Parameters.ParamByName('@Name').Value := ANameParam;

Обнаружилось: что в некоторых случаях такой подход несрабатывает, и нужно добавить Refresh:
Код

      Parameters.ParseSQL(SQL.Text, True);
      Parameters.Refresh;
      Parameters.ParamByName('@Name').Value := ANameParam;

А в других наоборот, с Refresh не работает и его дописывать ни как нельзя. Типы параметров в обоих случаях строковые. Разница лишь в длине SQL 71 (работает без Refresh) и 51 (работает только с Refresh).
Если кто сталкивался, помогите решить проблему. Как программно определить какой метод использовать для корректного определения параметров?

Автор: pseud 16.9.2010, 09:35
Цитата(Avers @  15.9.2010,  22:00 Найти цитируемый пост)
Обнаружилось: что в некоторых случаях такой подход несрабатывает, и нужно добавить Refresh:

у меня нет TADOConnection.
я бросаю на форму компонент TADOQuery.
задаю ему SQL и пытаюсь сделать Parameters.Refresh;.
получаю:
Цитата

---------------------------
Project1
---------------------------
Missing Connection or ConnectionString.
---------------------------
ОК   
---------------------------

т.е. для отрабатывания Refresh нужен открытый коннекшен. А это глупость, ведь я всего лишь хочу, чтобы автосоздались параметры согласно заданному SQL

Добавлено через 9 минут и 10 секунд
в функции
Код

function TParameters.ParseSQL(SQL: string; DoCreate: Boolean): string;

нет никаких ограничений на размер SQL. Возможно он не может "съесть" какие-то названия параметров.

Автор: Frees 16.9.2010, 09:44
Цитата(pseud @  16.9.2010,  12:35 Найти цитируемый пост)
А это глупость,

парсит запрос драйвер поэтому конект и нужен

Автор: pseud 16.9.2010, 09:55
Цитата(Frees @  16.9.2010,  09:44 Найти цитируемый пост)
парсит запрос драйвер поэтому конект и нужен 

Понял. Возможно это и не плохо. 
Получается необходимо ожидать/обрабатывать обрыв соединения каждый раз в двух местах. 
1. При подговотоке параметров.
2. При выполнении запроса.
Ну это так - тонкости.

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