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

Обсуждение возникших проблем, предложений и ошибок UniDAC компонентов
Akella
Сообщения: 217
Зарегистрирован: Пн 02 апр 2012 14:41

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

Сообщение Akella » Вс 10 май 2020 16:53

все запросы генерируются, хоть и не совсем правильно, а вот запрос 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 Вс 10 май 2020 17:15, всего редактировалось 2 раза.

Akella
Сообщения: 217
Зарегистрирован: Пн 02 апр 2012 14:41

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

Сообщение Akella » Вс 10 май 2020 16:57

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

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

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

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

INSERT INTO TABLE1
  (ID, NAME)
VALUES
  (:ID, :NAME)
Что сделать, чтобы SQL-генератор программно в runtime генерировал правильные запросы?

oleg0k
Devart Team
Сообщения: 21
Зарегистрирован: Вт 10 мар 2020 17:46

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

Сообщение oleg0k » Пт 22 май 2020 21:05

Добрый день, извините за долгий ответ

Для Update третий параметр GenerateSQL устанавливайте в False, и для генерирования запроса с именованными параметрами:

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

  TDBAccessUtils.SQLGenerator(UniQuery1).SubstituteParamName := False;
  UniQuery1.SQLUpdate.Text := TDBAccessUtils.SQLGenerator(UniQuery1).GenerateSQL(TDAParamsInfo.Create(TDAParamInfo) , _stUpdate, False);
wbr, Oleg
Devart Team

Akella
Сообщения: 217
Зарегистрирован: Пн 02 апр 2012 14:41

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

Сообщение Akella » Сб 23 май 2020 09:33

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

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

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);// генерируем остальные запросы

oleg0k
Devart Team
Сообщения: 21
Зарегистрирован: Вт 10 мар 2020 17:46

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

Сообщение oleg0k » Ср 27 май 2020 18:30

Добрый день,
Поведение с Insert не удалось воспроизвести.
Чтобы мы могли дать вам развернутый ответ, составьте демо пример, заархивируйте в zip и пришлите через форму на нашем сайте:
https://devart.com/company/contactform.html

wbr, Oleg
Devart Team

Akella
Сообщения: 217
Зарегистрирован: Пн 02 апр 2012 14:41

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

Сообщение Akella » Ср 27 май 2020 18:37

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

А поведение с именованными параметрами?
Мне так и не удалось сгенерировать запрос с именованными параметрами.

Akella
Сообщения: 217
Зарегистрирован: Пн 02 апр 2012 14:41

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

Сообщение Akella » Чт 28 май 2020 08:26

В общем, проблемы проявляются, если у TUniQuery включить SmartFetch.

Akella
Сообщения: 217
Зарегистрирован: Пн 02 апр 2012 14:41

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

Сообщение Akella » Вт 09 июн 2020 07:19

up

oleg0k
Devart Team
Сообщения: 21
Зарегистрирован: Вт 10 мар 2020 17:46

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

Сообщение oleg0k » Пт 12 июн 2020 15:31

Добрый день,
Составьте небольшой пример, демонстрирующий все интересующие вас вопросы, заархивируйте в zip и пришлите через форму на нашем сайте:
https://devart.com/company/contactform.html

wbr, Oleg
Devart Team

Akella
Сообщения: 217
Зарегистрирован: Пн 02 апр 2012 14:41

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

Сообщение Akella » Чт 06 авг 2020 12:13

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

Если я использую вышеуказанную процедуру 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."

oleg0k
Devart Team
Сообщения: 21
Зарегистрирован: Вт 10 мар 2020 17:46

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

Сообщение oleg0k » Пн 10 авг 2020 12:05

Здравствуйте,

Проблема с утечками памяти не связана с работой наших компонентов. В вашем коде вы создаёте экземпляры TDAParamsInfo, которые потом не освобождаете.
Уточните также, о какой проблеме со свойством SmartFetch идет речь?

wbr, Oleg
Devart Team

Akella
Сообщения: 217
Зарегистрирован: Пн 02 апр 2012 14:41

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

Сообщение Akella » Чт 08 июл 2021 08:22

Добрый день. Еще маленькая проблема.
Если датасет пустой, т.е. данных в таблице нет, то вываливает AV

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

  DAParamsInfo := TDAParamsInfo.Create(TDAParamInfo);
  try
    try
    
на этой строке ->>      UniQuery.SQLInsert.Text  := TDBAccessUtils.SQLGenerator(UniQuery).GenerateSQL(DAParamsInfo, _stInsert, true);

EvgeniyM
Сообщения: 8
Зарегистрирован: Пт 14 май 2021 08:21

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

Сообщение EvgeniyM » Чт 08 июл 2021 09:53

Добрый день,
К сожалению, предоставленных данных недостаточно для воспроизведения описанного поведения.
Составьте и отправьте нам небольшой пример, демонстрирующий описанное поведение, а также сценарии DDL для создания и заполнения тестовых объектов базы данных.
Вы можете отправить их используя форму на нашем:
https://www.devart.com/company/contactform.html

С уважением,
Евгений

Akella
Сообщения: 217
Зарегистрирован: Пн 02 апр 2012 14:41

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

Сообщение Akella » Пн 12 июл 2021 09:46

Хм... странно, я вообще убрал из кода свою процедуру, которая генерирует тексты update-запросов для этой компоненты uniQuery1.
Ошибка исчезла. Но...
Но все равно данные в базу через этот же самый uniQuery1 добавляются и редактируются.
Получается, что без моего ведома компонента uniQuery1 сама создает update-запросы автоматически? Или это регулируется каким-то свойством?

EvgeniyM
Сообщения: 8
Зарегистрирован: Пт 14 май 2021 08:21

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

Сообщение EvgeniyM » Пн 12 июл 2021 12:36

Если UniQuery1.SQLUpdate.Text установлено в пустую строку, UniDAC автоматически сформирует запрос на обновление
Если свойство SQLInsert, SQLUpdate, SQLDelete, SQLRefresh не пустое, например сгенерированное в дизантайме или установленное вручную, UniDAC будет использовать SQL запрос указанный в данном свойстве. Если свойство установлено в пустую строку UniDAC будет автоматически формировать необходимые SQL запросы при выполнении соответствующих операций. В большинстве случаев вам не нужно указывать свойства SQLInsert, SQLUpdate, SQLDelete, SQLRefresh. Вам следует устанавливать эти свойства вручную только в специфицеских ситуациях, когда автоматически сформированный SQL-запрос возвращает некорректный результат (например использование complex запросов).
С уважением,
Евгений

Закрыто