powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Насчет свойств формирования SQL запроса
25 сообщений из 64, страница 2 из 3
Насчет свойств формирования SQL запроса
    #39558252
Sashaua
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon,

У меня в классе есть метод выполняющий запросы
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
procedure TClients.getSQLrequest(sql: string);
begin
 with fDataModule_modelwork do begin
  try
  IBQuery_SQLrequest.SQL.Clear;
  IBQuery_SQLrequest.SQL.Add(sql);
  IBQuery_SQLrequest.Open;
  except
  on e: exception do
  MessageDlg('Ошибка выполнения запроса'+#13#10+e.message, mtError, [mbOk], 0);
  end;
 end;
end;



Есть методы через которые запросы отправляються

Код: pascal
1.
2.
3.
4.
procedure TClients.getClients_list();
begin
getSQLrequest('select ID,NAME from CLIENTS');
end;



С таким запросом проблем нет, а вот если в запрос необходимо передать параметр например 'select ID,NAME from CLIENTS where id=:id_client' нехочеться в сам запрос вставлять переменные например ('select ID,NAME from CLIENTS where id='+id_client ) а передавать через ParamByName
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558286
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sashaua,

Можно в сделать не процедуру, а функцию, которая вернет Query. Что-то в таком роде (только каркас):

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
function GetSQLQuery(Sql:string):TIB_Query;
begin
   Result:=TIBQuery.Create(nil);   // тут могут быть варианты, можно взять уже созданную где-то Query
   Result.SQL.Text:=Sql;
   Result.Prepare;
end;


var Q:TIBQuery;

Q:=GetSQLQuery('select name from clients where id=:id');
Q.ParamByName('id').AsInteger:=123;
Q.Open;
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558291
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Установку транзакции и соединения, старт транзакции и т.п. - я опустил если что.
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558308
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMaster,

в этом случае лучше сделать следующий шаг, обойтись и без процедуры, и без функции, а воспользоваться нормальным компонентом, настроенным в дизайн-тайме.

Функция типа "сделай запрос" нужна тогда, когда требуется реализовать какую-то мелочь, под которую жалко и несоразмерно использовать тяжёлую артиллерию. Впрочем, со временем я всё больше убеждаюсь, что потребность в таких функциях означает плохой дизайн приложения. Но тем не менее, в идеале API для неё выглядит примерно так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
{ Сформировать настроенный dataset }
function MakeQuery(const ASQL: string; Params: array of const): TXYZQuery;

{ Выполнить запрос и вернуть двумерный массив значений }
function SelectSQL(const ASQL: string; Params: array of const): variant;

{ Выполнить DML/анонимный блок и вернуть out-параметры }
function ExecSQL(const ASQL: string; Params: array of const): variant;

{ Выполнить хранимку и вернуть out-параметры }
function ExecSP(const ASQL: string; Params: array of const): variant;


Три последних, соответственно, пользуются первой. Первая нужна, например, для более эффективного фетча в случае долгих запросов.
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558328
Sashauamakhaon,

У меня в классе есть метод выполняющий запросы
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
procedure TClients.getSQLrequest(sql: string);
begin
 with fDataModule_modelwork do begin
  try
  IBQuery_SQLrequest.SQL.Clear;
  IBQuery_SQLrequest.SQL.Add(sql);
  IBQuery_SQLrequest.Open;
  except
  on e: exception do
  MessageDlg('Ошибка выполнения запроса'+#13#10+e.message, mtError, [mbOk], 0);
  end;
 end;
end;



Есть методы через которые запросы отправляються

Код: pascal
1.
2.
3.
4.
procedure TClients.getClients_list();
begin
getSQLrequest('select ID,NAME from CLIENTS');
end;



С таким запросом проблем нет, а вот если в запрос необходимо передать параметр например 'select ID,NAME from CLIENTS where id=:id_client' нехочеться в сам запрос вставлять переменные например ('select ID,NAME from CLIENTS where id='+id_client ) а передавать через ParamByName

Для таких безобразий ("получить значение по-быстрому") класс, инкапсулирующий объект коннекта, имеет метод:

Код: pascal
1.
2.
3.
    function QueryValue(const aSQL: string; FieldNo: integer {"-1" - для изменений};
      ParamValues: array of variant; 
      aTransaction: TMyTransaction = nil (если не указано - создается "внутренняя транзакция")): Variant; overload;



Код: pascal
1.
2.
3.
  fId := fMyConnect.QueryValue('select id from MyTable where FullName = :FullName', 0, ['Хонда Икс Рэй']);
...
  fMyConnect.QueryValue('update MyTable set FullName = :FullName where id = :id', -1, ['Хонда Икс Рэй - 666', fId], fMyUpdateTransaction);
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558429
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer,

В одном проекте видел функционал, завязанный именно на динамическое создание Query. Такое впечатление, что пытались эмулировать LINQ или сгородить что-то свое. Пользоваться в принципе можно было, но я бы такого не делал, если проект большой достаточно.
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558441
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerDarkMaster,
Функция типа "сделай запрос" нужна тогда, когда требуется реализовать какую-то мелочь, под которую жалко и несоразмерно использовать тяжёлую артиллерию.

Поделюсь и своими наблюдениями :) Есть кучка подразделений, которым нужно время от времени посмотреть какой-то отчет (отчеты разные, часто меняются/дополняются). Для этого сделали подсистему, которая умеет строить список доступных для пользователя отчетов, брать текст SQL запроса из БД, при наличии параметров - строить форму для их ввода, выводить результаты в сетку и экспортировать при необходимости куда нужно. Весь код (подсистемы) влез в пару экранов + 1 dfm (форма с PageControl) - все делается с помощью динамически создаваемых Query. Вся работа по поддержке - написать запрос и внести его в специальную табличку вместо постоянной возьни в IDE с настройками в design-time. Как-то так.
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558478
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Могу кинуть самый главный кусок функции.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
  IBSQL.Close;
  IBSQL.SQL.Clear;
  if not IBSQL.Transaction.Active then
   IBSQL.Transaction.StartTransaction;
  s1 := UpperCase(Copy(s, 1, 6));
  if (s1 = 'UPDATE') or (s1 = 'INSERT') then
  begin
   List := TStringList.Create;
   try
    TempB := Pos('"', s);
    TempE := NPos('"', s, 2);
    s1 := s;
    while TempB > 0 do
    begin
     List.Add(ReplaceChr(CopyLim(s1, TempB, TempE), '', '"'));
     s1 := ReplaceStr(':Field' + IntToStr(List.Count), s1, TempB - 1, TempE);
     TempB := Pos('"', s1);
     TempE := NPos('"', s1, 2);
    end;
    IBSQL.SQL.Add(s1);
    for i1 := 0 to List.Count - 1 do
     IBSQL.ParamByName(Format('Field%d', [i1 + 1])).AsString := List.Strings[i1];
   finally
    FreeAndNil(List);
   end;
  end



Тут парочка частных функций. И местами частное исполнение. Но, думаю, идея будет понятна.
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558484
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon,

что это?
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558521
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДmakhaon,

что это?

Попытка применить параметры только для INSERT/UPDATE видимо. О том, что параметры могут быть для SELECT - догадываются, но значения не придают. О том, что двойные кавычки вполне себе легитимный символ для некоторых SQL серверов и даже диалектов внутри одного SQL сервера - наверное тоже. Ну и так - по мелочи (экранируемые символы по идее тоже лесом пойдут - не всматривался). Но это я так - брюзжу по-стариковски.
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558531
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMasterпараметры могут быть для SELECTи для execute. И прбелы могут вначале быть или другие незначащие символы. И Transaction может быть =nil...
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558547
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMaster,

я же написал - частный случай. для моего, частного, случая (FB), работает отлично 10+ лет. нужно - дописывайте по образу.
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558548
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

автори для execute. И прбелы могут вначале быть или другие незначащие символы. И Transaction может быть =nil...

у меня не может быть. ни то, ни другое.
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558554
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonМогу кинуть самый главный кусок функции.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
  IBSQL.Close;
  IBSQL.SQL.Clear;
  if not IBSQL.Transaction.Active then
   IBSQL.Transaction.StartTransaction;
  s1 := UpperCase(Copy(s, 1, 6));
  if (s1 = 'UPDATE') or (s1 = 'INSERT') then
  begin
   List := TStringList.Create;
   try
    TempB := Pos('"', s);
    TempE := NPos('"', s, 2);
    s1 := s;
    while TempB > 0 do
    begin
     List.Add(ReplaceChr(CopyLim(s1, TempB, TempE), '', '"'));
     s1 := ReplaceStr(':Field' + IntToStr(List.Count), s1, TempB - 1, TempE);
     TempB := Pos('"', s1);
     TempE := NPos('"', s1, 2);
    end;
    IBSQL.SQL.Add(s1);
    for i1 := 0 to List.Count - 1 do
     IBSQL.ParamByName(Format('Field%d', [i1 + 1])).AsString := List.Strings[i1];
   finally
    FreeAndNil(List);
   end;
  end



Тут парочка частных функций. И местами частное исполнение. Но, думаю, идея будет понятна.

А что оно делает ?
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558560
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schi,

Оно делает запросы с параметрами из просто запросов. Удобно - написал запрос и забыл.
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558561
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonDarkMaster,

я же написал - частный случай. для моего, частного, случая (FB), работает отлично 10+ лет. нужно - дописывайте по образу.

Та у меня собственно никаких претензий и нет - у самого лисапед такой системы в сарае припрятан :)
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558570
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonschi,

Оно делает запросы с параметрами из просто запросов. Удобно - написал запрос и забыл.А почему нельзя имена параметров ставить такими же, как имена полей?
Я лично так делаю и потом их заполнение - наглядно и понятно.
Передаю в подобную ф-цию имя таблицы и массив-список полей, и генерится такое:
INSERT INTO TABLE(ID,NAME) VALUES(:ID,:NAME)
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558572
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

1. Не стоит этот код воспринимать как догму :) Но как идею. Как будет реализовано - на усмотрение. Так называть, или по-другому, как удобно.

2. Мне удобно тем, что я пишу:

Код: pascal
1.
2.
MakeQuery(IBSQL1, Format('delete from fixes where fix_sel_str = "%s"', [SelStr]));
MakeQuery(IBSQL1, Format('insert into fixes (fix_sel_str, fix_data) values ("%s", "%s")', [SelStr, FixData]));


Функция сама разберется с параметрами.
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558581
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonYuRock,

1. Не стоит этот код воспринимать как догму :) Но как идею. Как будет реализовано - на усмотрение. Так называть, или по-другому, как удобно.

2. Мне удобно тем, что я пишу:

Код: pascal
1.
2.
MakeQuery(IBSQL1, Format('delete from fixes where fix_sel_str = "%s"', [SelStr]));
MakeQuery(IBSQL1, Format('insert into fixes (fix_sel_str, fix_data) values ("%s", "%s")', [SelStr, FixData]));



Функция сама разберется с параметрами.
Ниче не понял. Если ты уже значения туда загнал, зачем тогда параметры уже? Чтоб потом их поменять можно было еще? Ну так вот, менять их нагляднее, когда они называются как поля, а не Param1, Param2.
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558585
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon2. Мне удобно тем, что я пишу:
А инъектор о своём удобстве скромно умалчивает :)
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558611
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

авторНиче не понял. Если ты уже значения туда загнал, зачем тогда параметры уже?

затем, что на инсертах и апдейтах на некоторых серверах (подробностей за давностью не помню) просто не работает, валится с исключениями.
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558615
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonschi,

Оно делает запросы с параметрами из просто запросов. Удобно - написал запрос и забыл.

"Каждой хозяйке и не надо покупать этот агрегат. Его одного на весь город хватит. Он будет установлен где-нибудь в центре города, скажем, на Невском. И там будет оборудован ЕГКОЦ - Единый Городской Консервооткрывательный Центр. Это очень удобно. Вот, скажем, пришли к тебе гости, надо для них шпроты открыть. Ты просто берёшь свою консервную банку, быстренько выходишь на улицу, едешь в ЕГКОЦ. Там сдаёшь банку приёмщице, платишь пять копеек новыми и получаешь квитанцию. Приёмщица наклеивает на банку ярлычок и ставит её на конвейер. А ты идёшь себе в зал ожидания, садишься в кресло и смотришь короткометражный фильм на консервную тему. Вскоре тебя вызывают к окошечку, ты предъявлять квитанцию, получаешь открытую банку и спокойненько едешь домой на Васильевский. Удобно, правда?"

Вадим Шефнер, "Скромный гений"
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558628
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Жаль, что мы так и не услышали начальника транспортного цеха.

Михаил Жванецкий, "Собрание на ликеро-водочном заводе"
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558635
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonYuRock,

авторНиче не понял. Если ты уже значения туда загнал, зачем тогда параметры уже?

затем, что на инсертах и апдейтах на некоторых серверах (подробностей за давностью не помню) просто не работает, валится с исключениями.Некоторые сервера не поддерживают инсертов с константами? Только с параметрами?
...
Рейтинг: 0 / 0
Насчет свойств формирования SQL запроса
    #39558639
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

Возможно, всё заканчивалось исключением.
...
Рейтинг: 0 / 0
25 сообщений из 64, страница 2 из 3
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Насчет свойств формирования SQL запроса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]