Найдено 200 результатов

Akella
Пт 07 авг 2020 08:53
Форум: Universal Data Access Components
Тема: UniQuery-FetchRows и пагинация
Ответы: 10
Просмотры: 3577

Re: UniQuery-FetchRows и пагинация

Stellar писал(а): Чт 02 июл 2020 12:50 Больше информации о SmartFetch опции Вы можете прочитать в нашей он-лайн документации:
https://www.devart.com/unidac/docs/?dev ... ptions.htm
И где же там "больше информации"?
Наоборот - там той информации, которую написали вы здесь - вообще нет, не то чтобы "больше" :(
Akella
Чт 06 авг 2020 12:13
Форум: Universal Data Access Components
Тема: Не генерируется запрос _stUpdate (GenerateSQL)
Ответы: 10
Просмотры: 4474

Re: Не генерируется запрос _stUpdate (GenerateSQL)

Как убрать утечки памяти?

Если я использую вышеуказанную процедуру GenSQL(), то потом, при завершении приложения я получаю сообщение:
Unexpected Memory Leak
---------------------------
This application has leaked memory. The leaks ordered by size are:
22: 2 x UnicodeString
30: 4 x CRAccess.TDAParamsInfo, 7 x UnicodeString, 2 x Unknown
38: 1 x UnicodeString
46: 4 x System.Generics.Collections.TList<System.Classes.TCollectionItem>
54: 19 x CRAccess.TDAParamInfo, 1 x UnicodeString
94: 2 x Unknown
Я вижу, что в коде создается 4 раза объект TDAParamsInfo.Create(TDAParamInfo), вероятно, уничтожения нет.
Поэтому вопрос: как правильно уничтожить эти 4 объекта типа TDAParamsInfo которые создавались при генерации SQL-запросов?

Я отправлю тестовый пример, где воспроизводится проблема.
И ещё. Этот же тестовый пример показывает проблему со свойством SmartFetch.Enabled
Вот ссылка
https://files.dp.ua/ru/mWZ8wh6kRS

я хотел загрузить на (https://devart.com/company/contactform.html/) но не пускает сайт, пишет
"Error
Sorry, there was an error
Please report this error to support team."
Akella
Чт 28 май 2020 08:26
Форум: Universal Data Access Components
Тема: Не генерируется запрос _stUpdate (GenerateSQL)
Ответы: 10
Просмотры: 4474

Re: Не генерируется запрос _stUpdate (GenerateSQL)

В общем, проблемы проявляются, если у TUniQuery включить SmartFetch.
Akella
Ср 27 май 2020 18:37
Форум: Universal Data Access Components
Тема: Не генерируется запрос _stUpdate (GenerateSQL)
Ответы: 10
Просмотры: 4474

Re: Не генерируется запрос _stUpdate (GenerateSQL)

Ок, пришлю пример.

А поведение с именованными параметрами?
Мне так и не удалось сгенерировать запрос с именованными параметрами.
Akella
Сб 23 май 2020 09:33
Форум: Universal Data Access Components
Тема: Не генерируется запрос _stUpdate (GenerateSQL)
Ответы: 10
Просмотры: 4474

Re: Не генерируется запрос _stUpdate (GenerateSQL)

На счет именованных параметров вопрос.
Подскажите ,что не так в коде?

Код: Выделить всё

procedure GenSQL(UniQuery: TUniQuery; const aSelectSql: string);
begin
  UniQuery.SQL.Text := aSelectSql;
  UniQuery.KeyFields := 'id';
  UniQuery.Open;

  TDBAccessUtils.SQLGenerator(UniQuery).SubstituteParamName := False;// для генерирования запроса с именованными параметрами

  UniQuery.SQLInsert.Text  := TDBAccessUtils.SQLGenerator(UniQuery).GenerateSQL(TDAParamsInfo.Create(TDAParamInfo) , _stInsert, true);
  OutputDebugString(Pwidechar(UniQuery.SQLInsert.Text));

  UniQuery.SQLUpdate.Text  := TDBAccessUtils.SQLGenerator(UniQuery).GenerateSQL(TDAParamsInfo.Create(TDAParamInfo) , _stUpdate, False);// Для Update 3й параметр = False
  OutputDebugString(Pwidechar(UniQuery.SQLUpdate.Text));

  UniQuery.SQLDelete.Text  := TDBAccessUtils.SQLGenerator(UniQuery).GenerateSQL(TDAParamsInfo.Create(TDAParamInfo) , _stDelete, true);
  OutputDebugString(Pwidechar(UniQuery.SQLDelete.Text));

  UniQuery.SQLRefresh.Text := TDBAccessUtils.SQLGenerator(UniQuery).GenerateSQL(TDAParamsInfo.Create(TDAParamInfo) , _stRefresh, true);
  OutputDebugString(Pwidechar(UniQuery.SQLRefresh.Text));

end;
Результаты вот такие:
Debug Output:
select id, name "назва" from OPERATION
WHERE INSERT INTO OPERATION
(ID, NAME)
VALUES
(?, ?((ID=?) OR (ID=?) OR (ID=?) OR (ID=?) OR (ID=?) OR (ID=?)) )


Debug Output:
UPDATE OPERATION
SET
ID = ?, NAME = ?
WHERE
ID = ?

Debug Output:
DELETE FROM OPERATION
WHERE
ID = ?

Debug Output:
SELECT ID AS IBC$0, NAME AS IBC$1 FROM OPERATION
WHERE
ID = ?
INSERT вообще странный какой-то

вот сам основной select запрос

Код: Выделить всё

select id, name "назва" from OPERATION

Еще добавлю кода:

Код: Выделить всё

    qRef.Conditions.Clear;
    qRef.sql.Text := 'select ' + IfThen(aFields.IsEmpty, 'id, name "назва"', aFields) + ' from ' + aTable;
    qRef.SpecificOptions.Values['KeyGenerator']  := aGenerator;
    qRef.SpecificOptions.Values['GeneratorMode'] := 'gmInsert';

    GenSQL(qRef, qRef.sql.Text);// генерируем остальные запросы
Akella
Пт 15 май 2020 07:09
Форум: Universal Data Access Components
Тема: Как правильно работать с транзакциями
Ответы: 19
Просмотры: 17870

Re: Как правильно работать с транзакциями

Да, разобрался уже, спасибо.

ЕМНИМ, то если у UniConnection AutoCommit отключен, то не важно в каком состоянии AutoCommit у UniQuery? Нужно всегда самому програмно подтверждать транзакцию даже если AutoCommit включен у UniQuery? Я правильно помню?
Akella
Вс 10 май 2020 16:57
Форум: Universal Data Access Components
Тема: Не генерируется запрос _stUpdate (GenerateSQL)
Ответы: 10
Просмотры: 4474

Re: Не генерируется запрос _stUpdate (GenerateSQL)

В чем "неправильность" запросов.
запросы генерируются в виде

Код: Выделить всё

INSERT INTO TABLE1
  (ID, NAME)
VALUES
  (?, ?)
Но если вставить select-запрос в редактор запросов TUniQuery и нажать там кнопку Generate SQL, то сгенерируется вот такой запрос, т.е. с именованными параметрами:

Код: Выделить всё

INSERT INTO TABLE1
  (ID, NAME)
VALUES
  (:ID, :NAME)
Что сделать, чтобы SQL-генератор программно в runtime генерировал правильные запросы?
Akella
Вс 10 май 2020 16:53
Форум: Universal Data Access Components
Тема: Не генерируется запрос _stUpdate (GenerateSQL)
Ответы: 10
Просмотры: 4474

Не генерируется запрос _stUpdate (GenerateSQL)

все запросы генерируются, хоть и не совсем правильно, а вот запрос Update вообще пустой.
на входе в aSelectSql запрос простой: select id, name from table1

Код: Выделить всё

procedure GenSQL(UniQuery: TUniQuery; const aSelectSql: string);
begin
  UniQuery.SQL.Text := aSelectSql;
  UniQuery.KeyFields := 'id';
  UniQuery.Open;

  UniQuery.SQLInsert.Text  := TDBAccessUtils.SQLGenerator(UniQuery).GenerateSQL(TDAParamsInfo.Create(TDAParamInfo) , _stInsert, true);
  OutputDebugString(Pwidechar(UniQuery.SQLInsert.Text));

  UniQuery.SQLUpdate.Text  := TDBAccessUtils.SQLGenerator(UniQuery).GenerateSQL(TDAParamsInfo.Create(TDAParamInfo) , _stUpdate, true);
  OutputDebugString(Pwidechar(UniQuery.SQLUpdate.Text));

  UniQuery.SQLDelete.Text  := TDBAccessUtils.SQLGenerator(UniQuery).GenerateSQL(TDAParamsInfo.Create(TDAParamInfo) , _stDelete, true);
  OutputDebugString(Pwidechar(UniQuery.SQLDelete.Text));

  UniQuery.SQLRefresh.Text := TDBAccessUtils.SQLGenerator(UniQuery).GenerateSQL(TDAParamsInfo.Create(TDAParamInfo) , _stRefresh, true);
  OutputDebugString(Pwidechar(UniQuery.SQLRefresh.Text));


  //UniQuery.close;
end;
В UniQuery.Oprions включен параметр "foTableAliasAndField".
UniDAC 8.0.1, Delphi Rio.
Akella
Сб 09 май 2020 22:24
Форум: Universal Data Access Components
Тема: Как правильно работать с транзакциями
Ответы: 19
Просмотры: 17870

Re: Как правильно работать с транзакциями

AndreyZ писал(а): Пн 11 июн 2012 08:07 MySQL не поддерживает множественные транзакции
Теперь вопрос по СУБД Firebird 3, которая поддерживает множественные транзакции.
Как правильно управлять транзакциями вручную?
Т.е. мне надо открыть транзацию, сделать много изменений и закрыть транзакцию либо откатить все изменения, если возникла ошибка в процессе изменения.

Код: Выделить всё

var
q: TUniSQL;
begin
...
   q.SQL.Text := 'update table1 set region = :region where id = :id;
    q.Transaction := transSqlExec;// назначаем "пишущую" транзакцию.
    q.Transaction.StartTransaction;// 
    запускаем цикл множественного изменения записей
    for I := 0 to ...
    begin
      q.ParamByName()...
      q.Execute;  
    end;
    
    q.Transaction.Rollback;// отменяю все сделанные изменения
выполняю код, проверяю, а данные в базу записались.
Почему нет отката изменения?


P.S. к UniConnection по умолчанию подключена транзакция "читающая", с параметрами: read;nowait;rec_version;read_committed
Akella
Сб 29 фев 2020 16:44
Форум: Universal Data Access Components
Тема: пропадает значение параметра после Conditions.Add
Ответы: 5
Просмотры: 3792

Re: пропадает значение параметра после Conditions.Add

Пример для первого вопрос отправил и вот картинка
http://prntscr.com/r9ijfk
где видно, что второй параметр пуст.
Akella
Сб 29 фев 2020 16:21
Форум: Universal Data Access Components
Тема: Как ПРАВИЛЬНО работать с Conditions.Enable/Disable?
Ответы: 3
Просмотры: 3460

Re: Как ПРАВИЛЬНО работать с Conditions.Enable/Disable?

Ещё вопрос.
Нормально ли вызывать UniQuery.Conditions.Enable несколько раз подряд перед тем, как вызвать Open?

Почему такой вопрос.
Предыстория.
Есть код добавления условий с параметрами.

Код: Выделить всё

    if DateTimePicker1.DateTime <> 0 then
      qData.Conditions.Add('lcd_min','A.LCD >= :LCDMIN', True);
      
    if DateTimePicker2.DateTime <> 0 then
      qData.Conditions.Add('lcd_max','A.LCD <= :LCDMAX', True);
Как я понял, то в SQL-запрос датасета параметры попадают только после вызова UniQuery.Conditions.Enable.
Таким образом получается, что условие приходится добавлять как бы дважды. Первый раз добавляешь условие с параметром, а потом нужно ещё и параметр заполнить.

т.е. выполнить ещё одну проверку

Код: Выделить всё

    if Assigned(qData.Params.FindParam('LCDMIN')) then
      qData.ParamByName('LCDMIN').AsDateTime := DateTimePicker1.DateTime;
      
    if Assigned(qData.Params.FindParam('LCDMAX')) then
      qData.ParamByName('LCDMAX').AsDateTime := DateTimePicker2.DateTime;
я к тому, что было бы удобней так:

Код: Выделить всё

if DateTimePicker1.DateTime <> 0 then
begin
     qData.Conditions.Add('lcd_min','A.LCD >= :LCDMIN', True);
     qData.ParamByName('LCDMIN').AsDateTime := DateTimePicker.DateTime;
end;
Теперь возвращаемся к вопросу про множественный вызов метода Enable. А можно ли делать так:

Код: Выделить всё

qData.Close;

if DateTimePicker1.DateTime <> 0 then
begin
      qData.Conditions.Add('lcd_min','A.LCD >= :LCDMIN', True);
      UniQuery.Conditions.Enable;
     qData.ParamByName('LCDMIN').AsDateTime := DateTimePicker.DateTime;
end;

if DateTimePicker2.DateTime <> 0 then
begin
      qData.Conditions.Add('lcd_max','A.LCD <= :LCDMAX', True);
      UniQuery.Conditions.Enable;
      qData.ParamByName('LCDMAX').AsDateTime := DateTimePicker2.DateTime;     
end;      

UniQuery.Open;
Akella
Сб 29 фев 2020 16:06
Форум: Universal Data Access Components
Тема: Как ПРАВИЛЬНО работать с Conditions.Enable/Disable?
Ответы: 3
Просмотры: 3460

Как ПРАВИЛЬНО работать с Conditions.Enable/Disable?

Не смог найти в справке и в документации некоторые ответы на мои вопрос. Например, как правильно использовать UniQuery.Conditions.Enable/Disable у функционала условий.

Не до конца понятно: если несколько раз добавляешь условия, то нужно ли перед этим вызывать Disable?

Достаточно ли просто того, что я вызову UniQuery.Conditions.Enable перед UniQuery.Open? Или обязательно/желательно выполнить такую проверку:
UniQuery.Conditions.Count > 0 then
UniQuery.Conditions.Enable;
UniQuery.Conditions.Enable нужно вызывать только после построения всех условий и перед Open или Conditions.Enable нужно/можно вызывать перед началом добавления условий?
Akella
Сб 29 фев 2020 08:54
Форум: Universal Data Access Components
Тема: пропадает значение параметра после Conditions.Add
Ответы: 5
Просмотры: 3792

Re: пропадает значение параметра после Conditions.Add

Пока создавал тестовый проект, появилась ещё одна проблема после того, как я заменил текст макроса.
И эта ошибка происходит, если включено свойство SmartFetch.
Project raised exception class EIBCError with message 'Dynamic SQL Error
SQL error code = -204
Ambiguous field name between table TYPES and table TABLE1
ID'.

Код: Выделить всё

procedure TForm1.Button1Click(Sender: TObject);
Var
 i: integer;
begin
  UniConnection1.Connect;

  UniQuery1.close;
  UniQuery1.Conditions.Clear;

  UniQuery1.MacroByName('TYPES').Value := 'LEFT JOIN TYPES T ON T.ID = A.ID_TYPE AND T.USERNAME = :USERNAME';
  UniQuery1.ParamByName('USERNAME').AsString := 'user';


  UniQuery1.open;<<< ошибка при открытии


  UniQuery1.close;

  UniQuery1.Conditions.Add('tname', 'T.NAME = :TNAME', True);
  UniQuery1.Conditions.Enable;
  UniQuery1.ParamByName('TNAME').AsString := 'qqqq';

  UniQuery1.Conditions.Add('tname', 'T.ID > 10', True);
  Memo1.Lines.Add(UniQuery1.FinalSQL);
  UniQuery1.open;

  Memo1.Lines.Add(UniQuery1.FinalSQL);


  Memo1.Lines.Add('');
  Memo1.Lines.Add('params');
  for I := 0 to pred(UniQuery1.Params.Count) do
    Memo1.Lines.Add(UniQuery1.Params[i].Name + ' = ' + UniQuery1.Params[i].AsString);

end;
Тестовый проект я отправлю со страницы ContactForm.

Я забыл добавить, что база для Firebird 3 (UTF8).

Запрос, который выдает FinalSQL, вполне нормальный и в IBExpert ID он выполняется без ошибок

Код: Выделить всё

SELECT
  A.ID,
  A.NAME NAME_USER,
  A.REMARK

  FROM TABLE1 A
  LEFT JOIN TYPES T ON T.ID = A.ID_TYPE AND T.USERNAME = :USERNAME
Akella
Чт 27 фев 2020 14:29
Форум: Universal Data Access Components
Тема: пропадает значение параметра после Conditions.Add
Ответы: 5
Просмотры: 3792

пропадает значение параметра после Conditions.Add

Delphi Tokyo, UniDAC 8.0.1.
В UniQuery добавлено 2 условия и 2 параметра. Потом нужно закрыть датасет, добавить ещё одно условие (без параметров) и снова открыть. Проблема в том, что сразу после добавления нового условия, т.е. после "UniQuery1.Conditions.Add" пропадает значение одного параметров, при этом имена параметров/условий не пересекаются (т.е. разные).

сделал такой пример.

Код: Выделить всё

procedure SetCondVal(uniQuery: TuniQuery; const Name, Val: string);
Var
  Cond: TDACondition;
  q: integer;
  n, v: string;
begin
  Cond := uniQuery.Conditions.Find(Name);
  
// здесь значение параметра (LCDMIN) ещё на месте
  for q := 0 to pred(uniQuery.ParamCount) do
  begin
    n := uniQuery.Params[q].Name;
    v := uniQuery.Params[q].AsString;
    v := v;// для бряки
  end;

  if Assigned(Cond) then
  begin
    Cond.Value := Val;
    Cond.Enable;
  end
  else
    uniQuery.Conditions.Add(Name, Val, True);// это условие выполняется

// здесь значение параметра (LCDMIN) уже потерялось
  for q := 0 to pred(uniQuery.ParamCount) do
  begin
    n := uniQuery.Params[q].Name;
    v := uniQuery.Params[q].AsString;
    v := v;// для бряки
  end;
end;
вот 4 снимка, на них видна хронология
http://prntscr.com/r8hrbx
http://prntscr.com/r8hs9s

http://prntscr.com/r8hskj
http://prntscr.com/r8hstg

Может это поможет решить проблему.
Параметр "TYPESIDS" добавлен с помощью макроса, а проблемный параметр "LCDMIN" добавлен с помощью Conditions.Add().

Я не выполняю ни Conditions.Disable, ни Conditions.Clear, просто сразу добавляю новое условие.
По идее, параметр не должен терять свое значение. Сам параметр же не теряется.